From 9f875160eaba1229e0e0bc2bedeeed670dd96f4d Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Sun, 8 Sep 2024 17:31:55 +0200 Subject: [PATCH] Make template initialization not ejected by default --- .../shared/downloadKeycloakDefaultTheme.ts | 2 +- src/login/KcContext/KcContext.ts | 1 - src/login/Template.tsx | 71 +------------ src/login/useInitTemplate.ts | 99 +++++++++++++++++++ 4 files changed, 104 insertions(+), 69 deletions(-) create mode 100644 src/login/useInitTemplate.ts diff --git a/scripts/shared/downloadKeycloakDefaultTheme.ts b/scripts/shared/downloadKeycloakDefaultTheme.ts index f5678ce6..f7dddea3 100644 --- a/scripts/shared/downloadKeycloakDefaultTheme.ts +++ b/scripts/shared/downloadKeycloakDefaultTheme.ts @@ -8,7 +8,7 @@ import { assert, type Equals } from "tsafe/assert"; const KEYCLOAK_VERSION = { FOR_LOGIN_THEME: "25.0.4", FOR_ACCOUNT_MULTI_PAGE: "21.1.2", - LAST_24: "24.0.4" + LAST_24: "24.0.6" } as const; export async function downloadKeycloakDefaultTheme(params: { diff --git a/src/login/KcContext/KcContext.ts b/src/login/KcContext/KcContext.ts index a091225e..819f8c21 100644 --- a/src/login/KcContext/KcContext.ts +++ b/src/login/KcContext/KcContext.ts @@ -152,7 +152,6 @@ export declare namespace KcContext { authenticationSession?: { authSessionId: string; tabId: string; - ssoLoginInOtherTabsUrl: string; }; properties: {}; "x-keycloakify": { diff --git a/src/login/Template.tsx b/src/login/Template.tsx index eebb0c31..ee94ab79 100644 --- a/src/login/Template.tsx +++ b/src/login/Template.tsx @@ -3,11 +3,10 @@ import { assert } from "keycloakify/tools/assert"; import { clsx } from "keycloakify/tools/clsx"; import type { TemplateProps } from "keycloakify/login/TemplateProps"; import { getKcClsx } from "keycloakify/login/lib/kcClsx"; -import { useInsertScriptTags } from "keycloakify/tools/useInsertScriptTags"; -import { useInsertLinkTags } from "keycloakify/tools/useInsertLinkTags"; import { useSetClassName } from "keycloakify/tools/useSetClassName"; import type { I18n } from "./i18n"; import type { KcContext } from "./KcContext"; +import { useInitTemplate } from "keycloakify/login/useInitTemplate"; export default function Template(props: TemplateProps) { const { @@ -30,7 +29,7 @@ export default function Template(props: TemplateProps) { const { msg, msgStr, getChangeLocaleUrl, labelBySupportedLanguageTag, currentLanguageTag } = i18n; - const { realm, locale, auth, url, message, isAppInitiatedAction, authenticationSession, scripts } = kcContext; + const { realm, locale, auth, url, message, isAppInitiatedAction } = kcContext; useEffect(() => { document.title = documentTitle ?? msgStr("loginTitle", kcContext.realm.displayName); @@ -46,71 +45,9 @@ export default function Template(props: TemplateProps) { className: bodyClassName ?? kcClsx("kcBodyClass") }); - useEffect(() => { - const { currentLanguageTag } = locale ?? {}; + const { isReadyToRender } = useInitTemplate({ kcContext, doUseDefaultCss }); - if (currentLanguageTag === undefined) { - return; - } - - const html = document.querySelector("html"); - assert(html !== null); - html.lang = currentLanguageTag; - }, []); - - const { areAllStyleSheetsLoaded } = useInsertLinkTags({ - componentOrHookName: "Template", - hrefs: !doUseDefaultCss - ? [] - : [ - `${url.resourcesCommonPath}/node_modules/@patternfly/patternfly/patternfly.min.css`, - `${url.resourcesCommonPath}/node_modules/patternfly/dist/css/patternfly.min.css`, - `${url.resourcesCommonPath}/node_modules/patternfly/dist/css/patternfly-additions.min.css`, - `${url.resourcesCommonPath}/lib/pficon/pficon.css`, - `${url.resourcesPath}/css/login.css` - ] - }); - - const { insertScriptTags } = useInsertScriptTags({ - componentOrHookName: "Template", - scriptTags: [ - { - type: "module", - src: `${url.resourcesPath}/js/menu-button-links.js` - }, - ...(authenticationSession === undefined - ? [] - : [ - { - type: "module", - textContent: [ - `import { checkCookiesAndSetTimer } from "${url.resourcesPath}/js/authChecker.js";`, - ``, - `checkCookiesAndSetTimer(`, - ` "${authenticationSession.authSessionId}",`, - ` "${authenticationSession.tabId}",`, - ` "${url.ssoLoginInOtherTabsUrl}"`, - `);` - ].join("\n") - } as const - ]), - ...scripts.map( - script => - ({ - type: "text/javascript", - src: script - }) as const - ) - ] - }); - - useEffect(() => { - if (areAllStyleSheetsLoaded) { - insertScriptTags(); - } - }, [areAllStyleSheetsLoaded]); - - if (!areAllStyleSheetsLoaded) { + if (!isReadyToRender) { return null; } diff --git a/src/login/useInitTemplate.ts b/src/login/useInitTemplate.ts new file mode 100644 index 00000000..5da30ef1 --- /dev/null +++ b/src/login/useInitTemplate.ts @@ -0,0 +1,99 @@ +import { useEffect } from "react"; +import { assert } from "keycloakify/tools/assert"; +import { useInsertScriptTags } from "keycloakify/tools/useInsertScriptTags"; +import { useInsertLinkTags } from "keycloakify/tools/useInsertLinkTags"; +import { KcContext } from "keycloakify/login/KcContext/KcContext"; + +export type KcContextLike = { + url: { + resourcesCommonPath: string; + resourcesPath: string; + ssoLoginInOtherTabsUrl: string; + }; + locale?: { + currentLanguageTag: string; + }; + scripts: string[]; + authenticationSession?: { + authSessionId: string; + tabId: string; + }; +}; + +assert(); +assert(); + +export function useInitTemplate(params: { + kcContext: KcContextLike; + doUseDefaultCss: boolean; +}) { + const { kcContext, doUseDefaultCss } = params; + + const { url, locale, scripts, authenticationSession } = kcContext; + + useEffect(() => { + const { currentLanguageTag } = locale ?? {}; + + if (currentLanguageTag === undefined) { + return; + } + + const html = document.querySelector("html"); + assert(html !== null); + html.lang = currentLanguageTag; + }, []); + + const { areAllStyleSheetsLoaded } = useInsertLinkTags({ + componentOrHookName: "Template", + hrefs: !doUseDefaultCss + ? [] + : [ + `${url.resourcesCommonPath}/node_modules/@patternfly/patternfly/patternfly.min.css`, + `${url.resourcesCommonPath}/node_modules/patternfly/dist/css/patternfly.min.css`, + `${url.resourcesCommonPath}/node_modules/patternfly/dist/css/patternfly-additions.min.css`, + `${url.resourcesCommonPath}/lib/pficon/pficon.css`, + `${url.resourcesPath}/css/login.css` + ] + }); + + const { insertScriptTags } = useInsertScriptTags({ + componentOrHookName: "Template", + scriptTags: [ + { + type: "module", + src: `${url.resourcesPath}/js/menu-button-links.js` + }, + ...(authenticationSession === undefined + ? [] + : [ + { + type: "module", + textContent: [ + `import { checkCookiesAndSetTimer } from "${url.resourcesPath}/js/authChecker.js";`, + ``, + `checkCookiesAndSetTimer(`, + ` "${authenticationSession.authSessionId}",`, + ` "${authenticationSession.tabId}",`, + ` "${url.ssoLoginInOtherTabsUrl}"`, + `);` + ].join("\n") + } as const + ]), + ...scripts.map( + script => + ({ + type: "text/javascript", + src: script + }) as const + ) + ] + }); + + useEffect(() => { + if (areAllStyleSheetsLoaded) { + insertScriptTags(); + } + }, [areAllStyleSheetsLoaded]); + + return { isReadyToRender: areAllStyleSheetsLoaded }; +}