Fully sync login template with Keycloak 24

This commit is contained in:
Joseph Garrone 2024-04-13 03:26:15 +02:00
parent de5bc82382
commit a7a3ec711b
4 changed files with 81 additions and 46 deletions

View File

@ -17,7 +17,7 @@ const isSilent = true;
const logger = getLogger({ isSilent }); const logger = getLogger({ isSilent });
async function main() { async function main() {
const keycloakVersion = "23.0.4"; const keycloakVersion = "24.0.2";
const thisCodebaseRootDirPath = getThisCodebaseRootDirPath(); const thisCodebaseRootDirPath = getThisCodebaseRootDirPath();

View File

@ -11,10 +11,9 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
displayInfo = false, displayInfo = false,
displayMessage = true, displayMessage = true,
displayRequiredFields = false, displayRequiredFields = false,
displayWide = false,
showAnotherWayIfPresent = true,
headerNode, headerNode,
showUsernameNode = null, showUsernameNode = null,
socialProvidersNode = null,
infoNode = null, infoNode = null,
kcContext, kcContext,
i18n, i18n,
@ -25,7 +24,7 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
const { getClassName } = useGetClassName({ doUseDefaultCss, classes }); const { getClassName } = useGetClassName({ doUseDefaultCss, classes });
const { msg, changeLocale, labelBySupportedLanguageTag, currentLanguageTag } = i18n; const { msg, msgStr, changeLocale, labelBySupportedLanguageTag, currentLanguageTag } = i18n;
const { realm, locale, auth, url, message, isAppInitiatedAction, authenticationSession } = kcContext; const { realm, locale, auth, url, message, isAppInitiatedAction, authenticationSession } = kcContext;
@ -85,12 +84,12 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
</div> </div>
</div> </div>
<div className={clsx(getClassName("kcFormCardClass"), displayWide && getClassName("kcFormCardAccountClass"))}> <div className={getClassName("kcFormCardClass")}>
<header className={getClassName("kcFormHeaderClass")}> <header className={getClassName("kcFormHeaderClass")}>
{realm.internationalizationEnabled && (assert(locale !== undefined), true) && locale.supported.length > 1 && ( {realm.internationalizationEnabled && (assert(locale !== undefined), true) && locale.supported.length > 1 && (
<div id="kc-locale"> <div className={getClassName("kcLocaleMainClass")} id="kc-locale">
<div id="kc-locale-wrapper" className={getClassName("kcLocaleWrapperClass")}> <div id="kc-locale-wrapper" className={getClassName("kcLocaleWrapperClass")}>
<div className="kc-dropdown" id="kc-locale-dropdown"> <div id="kc-locale-dropdown" className={clsx("menu-button-links", getClassName("kcLocaleDropDownClass"))}>
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */} {/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
<a href="#" id="kc-current-locale-link"> <a href="#" id="kc-current-locale-link">
{labelBySupportedLanguageTag[currentLanguageTag]} {labelBySupportedLanguageTag[currentLanguageTag]}
@ -105,6 +104,40 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
</li> </li>
))} ))}
</ul> </ul>
<button
tabIndex={1}
id="kc-current-locale-link"
aria-label={msgStr("languages" as any)}
aria-haspopup={true}
aria-expanded={false}
aria-controls="language-switch1"
>
{labelBySupportedLanguageTag[currentLanguageTag]}
</button>
<ul
role="menu"
tabIndex={-1}
aria-labelledby="kc-current-locale-link"
aria-activedescendant=""
id="language-switch1"
className={getClassName("kcLocaleListClass")}
>
{locale.supported.map(({ languageTag }, i) => (
<li key={languageTag} className={getClassName("kcLocaleListItemClass")} role="none">
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
<a
role="menuitem"
id={`language-${i}`}
className={getClassName("kcLocaleItemClass")}
href="#"
onClick={() => changeLocale(languageTag)}
>
{labelBySupportedLanguageTag[languageTag]}
</a>
</li>
))}
</ul>
</div> </div>
</div> </div>
</div> </div>
@ -134,10 +167,9 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
</div> </div>
<div className="col-md-10"> <div className="col-md-10">
{showUsernameNode} {showUsernameNode}
<div className={getClassName("kcFormGroupClass")}> <div id="kc-username" className={getClassName("kcFormGroupClass")}>
<div id="kc-username"> <label id="kc-attempted-username">{auth.attemptedUsername}</label>
<label id="kc-attempted-username">{auth?.attemptedUsername}</label> <a id="reset-login" href={url.loginRestartFlowUrl} aria-label={msgStr("restartLoginTooltip")}>
<a id="reset-login" href={url.loginRestartFlowUrl}>
<div className="kc-login-tooltip"> <div className="kc-login-tooltip">
<i className={getClassName("kcResetFlowIcon")}></i> <i className={getClassName("kcResetFlowIcon")}></i>
<span className="kc-tooltip-text">{msg("restartLoginTooltip")}</span> <span className="kc-tooltip-text">{msg("restartLoginTooltip")}</span>
@ -146,21 +178,18 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
</div> </div>
</div> </div>
</div> </div>
</div>
) : ( ) : (
<> <>
{showUsernameNode} {showUsernameNode}
<div className={getClassName("kcFormGroupClass")}> <div id="kc-username" className={getClassName("kcFormGroupClass")}>
<div id="kc-username"> <label id="kc-attempted-username">{auth.attemptedUsername}</label>
<label id="kc-attempted-username">{auth?.attemptedUsername}</label> <a id="reset-login" href={url.loginRestartFlowUrl} aria-label={msgStr("restartLoginTooltip")}>
<a id="reset-login" href={url.loginRestartFlowUrl}>
<div className="kc-login-tooltip"> <div className="kc-login-tooltip">
<i className={getClassName("kcResetFlowIcon")}></i> <i className={getClassName("kcResetFlowIcon")}></i>
<span className="kc-tooltip-text">{msg("restartLoginTooltip")}</span> <span className="kc-tooltip-text">{msg("restartLoginTooltip")}</span>
</div> </div>
</a> </a>
</div> </div>
</div>
</> </>
)} )}
</header> </header>
@ -168,13 +197,21 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
<div id="kc-content-wrapper"> <div id="kc-content-wrapper">
{/* App-initiated actions should not see warning messages about the need to complete the action during login. */} {/* App-initiated actions should not see warning messages about the need to complete the action during login. */}
{displayMessage && message !== undefined && (message.type !== "warning" || !isAppInitiatedAction) && ( {displayMessage && message !== undefined && (message.type !== "warning" || !isAppInitiatedAction) && (
<div className={clsx("alert", `alert-${message.type}`)}> <div
className={clsx(
`alert-${message.type}`,
getClassName("kcAlertClass"),
`pf-m-${message?.type === "error" ? "danger" : message.type}`
)}
>
<div className="pf-c-alert__icon">
{message.type === "success" && <span className={getClassName("kcFeedbackSuccessIcon")}></span>} {message.type === "success" && <span className={getClassName("kcFeedbackSuccessIcon")}></span>}
{message.type === "warning" && <span className={getClassName("kcFeedbackWarningIcon")}></span>} {message.type === "warning" && <span className={getClassName("kcFeedbackWarningIcon")}></span>}
{message.type === "error" && <span className={getClassName("kcFeedbackErrorIcon")}></span>} {message.type === "error" && <span className={getClassName("kcFeedbackErrorIcon")}></span>}
{message.type === "info" && <span className={getClassName("kcFeedbackInfoIcon")}></span>} {message.type === "info" && <span className={getClassName("kcFeedbackInfoIcon")}></span>}
</div>
<span <span
className="kc-feedback-text" className={getClassName("kcAlertTitleClass")}
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
"__html": message.summary "__html": message.summary
}} }}
@ -182,18 +219,9 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
</div> </div>
)} )}
{children} {children}
{auth !== undefined && auth.showTryAnotherWayLink && showAnotherWayIfPresent && ( {auth !== undefined && auth.showTryAnotherWayLink && (
<form <form id="kc-select-try-another-way-form" action={url.loginAction} method="post">
id="kc-select-try-another-way-form" <div className={getClassName("kcFormGroupClass")}>
action={url.loginAction}
method="post"
className={clsx(displayWide && getClassName("kcContentWrapperClass"))}
>
<div
className={clsx(
displayWide && [getClassName("kcFormSocialAccountContentClass"), getClassName("kcFormSocialAccountClass")]
)}
>
<div className={getClassName("kcFormGroupClass")}> <div className={getClassName("kcFormGroupClass")}>
<input type="hidden" name="tryAnotherWay" value="on" /> <input type="hidden" name="tryAnotherWay" value="on" />
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */} {/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
@ -211,6 +239,7 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
</div> </div>
</form> </form>
)} )}
{socialProvidersNode}
{displayInfo && ( {displayInfo && (
<div id="kc-info" className={getClassName("kcSignUpClass")}> <div id="kc-info" className={getClassName("kcSignUpClass")}>
<div id="kc-info-wrapper" className={getClassName("kcInfoAreaWrapperClass")}> <div id="kc-info-wrapper" className={getClassName("kcInfoAreaWrapperClass")}>

View File

@ -11,10 +11,10 @@ export type TemplateProps<KcContext extends KcContext.Common, I18nExtended exten
displayInfo?: boolean; displayInfo?: boolean;
displayMessage?: boolean; displayMessage?: boolean;
displayRequiredFields?: boolean; displayRequiredFields?: boolean;
displayWide?: boolean;
showAnotherWayIfPresent?: boolean; showAnotherWayIfPresent?: boolean;
headerNode: ReactNode; headerNode: ReactNode;
showUsernameNode?: ReactNode; showUsernameNode?: ReactNode;
socialProvidersNode?: ReactNode;
infoNode?: ReactNode; infoNode?: ReactNode;
children: ReactNode; children: ReactNode;
@ -27,6 +27,9 @@ export type ClassKey =
| "kcInfoAreaWrapperClass" | "kcInfoAreaWrapperClass"
| "kcFormButtonsWrapperClass" | "kcFormButtonsWrapperClass"
| "kcFormOptionsWrapperClass" | "kcFormOptionsWrapperClass"
| "kcLocaleDropDownClass"
| "kcLocaleListItemClass"
| "kcContentWrapperClass"
| "kcLogoIdP-facebook" | "kcLogoIdP-facebook"
| "kcAuthenticatorOTPClass" | "kcAuthenticatorOTPClass"
| "kcLogoIdP-bitbucket" | "kcLogoIdP-bitbucket"

View File

@ -9,6 +9,9 @@ export const { useGetClassName } = createUseClassName<ClassKey>({
"kcInfoAreaWrapperClass": undefined, "kcInfoAreaWrapperClass": undefined,
"kcFormButtonsWrapperClass": undefined, "kcFormButtonsWrapperClass": undefined,
"kcFormOptionsWrapperClass": undefined, "kcFormOptionsWrapperClass": undefined,
"kcLocaleDropDownClass": undefined,
"kcLocaleListItemClass": undefined,
"kcContentWrapperClass": undefined,
"kcLogoIdP-facebook": "fa fa-facebook", "kcLogoIdP-facebook": "fa fa-facebook",
"kcAuthenticatorOTPClass": "fa fa-mobile list-view-pf-icon-lg", "kcAuthenticatorOTPClass": "fa fa-mobile list-view-pf-icon-lg",