Use children prop for Template

This commit is contained in:
garronej 2023-03-21 02:36:13 +01:00
parent ec479c7e91
commit b3acecdcea
23 changed files with 1238 additions and 1336 deletions

View File

@ -15,12 +15,12 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
showAnotherWayIfPresent = true, showAnotherWayIfPresent = true,
headerNode, headerNode,
showUsernameNode = null, showUsernameNode = null,
formNode,
infoNode = null, infoNode = null,
kcContext, kcContext,
i18n, i18n,
doUseDefaultCss, doUseDefaultCss,
classes classes,
children
} = props; } = props;
const { getClassName } = useGetClassName({ const { getClassName } = useGetClassName({
@ -153,7 +153,7 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
/> />
</div> </div>
)} )}
{formNode} {children}
{auth !== undefined && auth.showTryAnotherWayLink && showAnotherWayIfPresent && ( {auth !== undefined && auth.showTryAnotherWayLink && showAnotherWayIfPresent && (
<form <form
id="kc-select-try-another-way-form" id="kc-select-try-another-way-form"

View File

@ -8,7 +8,6 @@ export type TemplateProps<KcContext extends KcContext.Common, I18nExtended exten
doUseDefaultCss: boolean; doUseDefaultCss: boolean;
classes?: Partial<Record<TemplateClassKey, string>>; classes?: Partial<Record<TemplateClassKey, string>>;
formNode: ReactNode;
displayInfo?: boolean; displayInfo?: boolean;
displayMessage?: boolean; displayMessage?: boolean;
displayRequiredFields?: boolean; displayRequiredFields?: boolean;
@ -17,6 +16,8 @@ export type TemplateProps<KcContext extends KcContext.Common, I18nExtended exten
headerNode: ReactNode; headerNode: ReactNode;
showUsernameNode?: ReactNode; showUsernameNode?: ReactNode;
infoNode?: ReactNode; infoNode?: ReactNode;
children: ReactNode;
}; };
export type TemplateClassKey = export type TemplateClassKey =

View File

@ -10,22 +10,17 @@ export default function Error(props: PageProps<Extract<KcContext, { pageId: "err
const { msg } = i18n; const { msg } = i18n;
return ( return (
<Template <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} displayMessage={false} headerNode={msg("errorTitle")}>
{...{ kcContext, i18n, doUseDefaultCss, classes }} <div id="kc-error-message">
displayMessage={false} <p className="instruction">{message.summary}</p>
headerNode={msg("errorTitle")} {client !== undefined && client.baseUrl !== undefined && (
formNode={ <p>
<div id="kc-error-message"> <a id="backToApplication" href={client.baseUrl}>
<p className="instruction">{message.summary}</p> {msg("backToApplication")}
{client !== undefined && client.baseUrl !== undefined && ( </a>
<p> </p>
<a id="backToApplication" href={client.baseUrl}> )}
{msg("backToApplication")} </div>
</a> </Template>
</p>
)}
</div>
}
/>
); );
} }

View File

@ -21,37 +21,33 @@ export default function IdpReviewUserProfile(props: PageProps<Extract<KcContext,
const [isFomSubmittable, setIsFomSubmittable] = useState(false); const [isFomSubmittable, setIsFomSubmittable] = useState(false);
return ( return (
<Template <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} headerNode={msg("loginIdpReviewProfileTitle")}>
{...{ kcContext, i18n, doUseDefaultCss, classes }} <form id="kc-idp-review-profile-form" className={getClassName("kcFormClass")} action={url.loginAction} method="post">
headerNode={msg("loginIdpReviewProfileTitle")} <UserProfileFormFields
formNode={ kcContext={kcContext}
<form id="kc-idp-review-profile-form" className={getClassName("kcFormClass")} action={url.loginAction} method="post"> onIsFormSubmittableValueChange={setIsFomSubmittable}
<UserProfileFormFields i18n={i18n}
kcContext={kcContext} getClassName={getClassName}
onIsFormSubmittableValueChange={setIsFomSubmittable} />
i18n={i18n} <div className={getClassName("kcFormGroupClass")}>
getClassName={getClassName} <div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
/> <div className={getClassName("kcFormOptionsWrapperClass")} />
<div className={getClassName("kcFormGroupClass")}>
<div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")} />
</div>
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
type="submit"
value={msgStr("doSubmit")}
disabled={!isFomSubmittable}
/>
</div>
</div> </div>
</form> <div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
} <input
/> className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
type="submit"
value={msgStr("doSubmit")}
disabled={!isFomSubmittable}
/>
</div>
</div>
</form>
</Template>
); );
} }

View File

@ -17,32 +17,31 @@ export default function Info(props: PageProps<Extract<KcContext, { pageId: "info
{...{ kcContext, i18n, doUseDefaultCss, classes }} {...{ kcContext, i18n, doUseDefaultCss, classes }}
displayMessage={false} displayMessage={false}
headerNode={messageHeader !== undefined ? <>{messageHeader}</> : <>{message.summary}</>} headerNode={messageHeader !== undefined ? <>{messageHeader}</> : <>{message.summary}</>}
formNode={ >
<div id="kc-info-message"> <div id="kc-info-message">
<p className="instruction"> <p className="instruction">
{message.summary} {message.summary}
{requiredActions !== undefined && ( {requiredActions !== undefined && (
<b>{requiredActions.map(requiredAction => msgStr(`requiredAction.${requiredAction}` as const)).join(",")}</b> <b>{requiredActions.map(requiredAction => msgStr(`requiredAction.${requiredAction}` as const)).join(",")}</b>
)}
</p>
{!skipLink && pageRedirectUri !== undefined ? (
<p>
<a href={pageRedirectUri}>{msg("backToApplication")}</a>
</p>
) : actionUri !== undefined ? (
<p>
<a href={actionUri}>{msg("proceedWithAction")}</a>
</p>
) : (
client.baseUrl !== undefined && (
<p>
<a href={client.baseUrl}>{msg("backToApplication")}</a>
</p>
)
)} )}
</div> </p>
} {!skipLink && pageRedirectUri !== undefined ? (
/> <p>
<a href={pageRedirectUri}>{msg("backToApplication")}</a>
</p>
) : actionUri !== undefined ? (
<p>
<a href={actionUri}>{msg("proceedWithAction")}</a>
</p>
) : (
client.baseUrl !== undefined && (
<p>
<a href={client.baseUrl}>{msg("backToApplication")}</a>
</p>
)
)}
</div>
</Template>
); );
} }

View File

@ -40,149 +40,6 @@ export default function Login(props: PageProps<Extract<KcContext, { pageId: "log
displayInfo={social.displayInfo} displayInfo={social.displayInfo}
displayWide={realm.password && social.providers !== undefined} displayWide={realm.password && social.providers !== undefined}
headerNode={msg("doLogIn")} headerNode={msg("doLogIn")}
formNode={
<div id="kc-form" className={clsx(realm.password && social.providers !== undefined && getClassName("kcContentWrapperClass"))}>
<div
id="kc-form-wrapper"
className={clsx(
realm.password &&
social.providers && [getClassName("kcFormSocialAccountContentClass"), getClassName("kcFormSocialAccountClass")]
)}
>
{realm.password && (
<form id="kc-form-login" onSubmit={onSubmit} action={url.loginAction} method="post">
<div className={getClassName("kcFormGroupClass")}>
{(() => {
const label = !realm.loginWithEmailAllowed
? "username"
: realm.registrationEmailAsUsername
? "email"
: "usernameOrEmail";
const autoCompleteHelper: typeof label = label === "usernameOrEmail" ? "username" : label;
return (
<>
<label htmlFor={autoCompleteHelper} className={getClassName("kcLabelClass")}>
{msg(label)}
</label>
<input
tabIndex={1}
id={autoCompleteHelper}
className={getClassName("kcInputClass")}
//NOTE: This is used by Google Chrome auto fill so we use it to tell
//the browser how to pre fill the form but before submit we put it back
//to username because it is what keycloak expects.
name={autoCompleteHelper}
defaultValue={login.username ?? ""}
type="text"
{...(usernameEditDisabled
? { "disabled": true }
: {
"autoFocus": true,
"autoComplete": "off"
})}
/>
</>
);
})()}
</div>
<div className={getClassName("kcFormGroupClass")}>
<label htmlFor="password" className={getClassName("kcLabelClass")}>
{msg("password")}
</label>
<input
tabIndex={2}
id="password"
className={getClassName("kcInputClass")}
name="password"
type="password"
autoComplete="off"
/>
</div>
<div className={clsx(getClassName("kcFormGroupClass"), getClassName("kcFormSettingClass"))}>
<div id="kc-form-options">
{realm.rememberMe && !usernameEditDisabled && (
<div className="checkbox">
<label>
<input
tabIndex={3}
id="rememberMe"
name="rememberMe"
type="checkbox"
{...(login.rememberMe
? {
"checked": true
}
: {})}
/>
{msg("rememberMe")}
</label>
</div>
)}
</div>
<div className={getClassName("kcFormOptionsWrapperClass")}>
{realm.resetPasswordAllowed && (
<span>
<a tabIndex={5} href={url.loginResetCredentialsUrl}>
{msg("doForgotPassword")}
</a>
</span>
)}
</div>
</div>
<div id="kc-form-buttons" className={getClassName("kcFormGroupClass")}>
<input
type="hidden"
id="id-hidden-input"
name="credentialId"
{...(auth?.selectedCredential !== undefined
? {
"value": auth.selectedCredential
}
: {})}
/>
<input
tabIndex={4}
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
name="login"
id="kc-login"
type="submit"
value={msgStr("doLogIn")}
disabled={isLoginButtonDisabled}
/>
</div>
</form>
)}
</div>
{realm.password && social.providers !== undefined && (
<div
id="kc-social-providers"
className={clsx(getClassName("kcFormSocialAccountContentClass"), getClassName("kcFormSocialAccountClass"))}
>
<ul
className={clsx(
getClassName("kcFormSocialAccountListClass"),
social.providers.length > 4 && getClassName("kcFormSocialAccountDoubleListClass")
)}
>
{social.providers.map(p => (
<li key={p.providerId} className={getClassName("kcFormSocialAccountListLinkClass")}>
<a href={p.loginUrl} id={`zocial-${p.alias}`} className={clsx("zocial", p.providerId)}>
<span>{p.displayName}</span>
</a>
</li>
))}
</ul>
</div>
)}
</div>
}
infoNode={ infoNode={
realm.password && realm.password &&
realm.registrationAllowed && realm.registrationAllowed &&
@ -197,6 +54,148 @@ export default function Login(props: PageProps<Extract<KcContext, { pageId: "log
</div> </div>
) )
} }
/> >
<div id="kc-form" className={clsx(realm.password && social.providers !== undefined && getClassName("kcContentWrapperClass"))}>
<div
id="kc-form-wrapper"
className={clsx(
realm.password &&
social.providers && [getClassName("kcFormSocialAccountContentClass"), getClassName("kcFormSocialAccountClass")]
)}
>
{realm.password && (
<form id="kc-form-login" onSubmit={onSubmit} action={url.loginAction} method="post">
<div className={getClassName("kcFormGroupClass")}>
{(() => {
const label = !realm.loginWithEmailAllowed
? "username"
: realm.registrationEmailAsUsername
? "email"
: "usernameOrEmail";
const autoCompleteHelper: typeof label = label === "usernameOrEmail" ? "username" : label;
return (
<>
<label htmlFor={autoCompleteHelper} className={getClassName("kcLabelClass")}>
{msg(label)}
</label>
<input
tabIndex={1}
id={autoCompleteHelper}
className={getClassName("kcInputClass")}
//NOTE: This is used by Google Chrome auto fill so we use it to tell
//the browser how to pre fill the form but before submit we put it back
//to username because it is what keycloak expects.
name={autoCompleteHelper}
defaultValue={login.username ?? ""}
type="text"
{...(usernameEditDisabled
? { "disabled": true }
: {
"autoFocus": true,
"autoComplete": "off"
})}
/>
</>
);
})()}
</div>
<div className={getClassName("kcFormGroupClass")}>
<label htmlFor="password" className={getClassName("kcLabelClass")}>
{msg("password")}
</label>
<input
tabIndex={2}
id="password"
className={getClassName("kcInputClass")}
name="password"
type="password"
autoComplete="off"
/>
</div>
<div className={clsx(getClassName("kcFormGroupClass"), getClassName("kcFormSettingClass"))}>
<div id="kc-form-options">
{realm.rememberMe && !usernameEditDisabled && (
<div className="checkbox">
<label>
<input
tabIndex={3}
id="rememberMe"
name="rememberMe"
type="checkbox"
{...(login.rememberMe
? {
"checked": true
}
: {})}
/>
{msg("rememberMe")}
</label>
</div>
)}
</div>
<div className={getClassName("kcFormOptionsWrapperClass")}>
{realm.resetPasswordAllowed && (
<span>
<a tabIndex={5} href={url.loginResetCredentialsUrl}>
{msg("doForgotPassword")}
</a>
</span>
)}
</div>
</div>
<div id="kc-form-buttons" className={getClassName("kcFormGroupClass")}>
<input
type="hidden"
id="id-hidden-input"
name="credentialId"
{...(auth?.selectedCredential !== undefined
? {
"value": auth.selectedCredential
}
: {})}
/>
<input
tabIndex={4}
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
name="login"
id="kc-login"
type="submit"
value={msgStr("doLogIn")}
disabled={isLoginButtonDisabled}
/>
</div>
</form>
)}
</div>
{realm.password && social.providers !== undefined && (
<div
id="kc-social-providers"
className={clsx(getClassName("kcFormSocialAccountContentClass"), getClassName("kcFormSocialAccountClass"))}
>
<ul
className={clsx(
getClassName("kcFormSocialAccountListClass"),
social.providers.length > 4 && getClassName("kcFormSocialAccountDoubleListClass")
)}
>
{social.providers.map(p => (
<li key={p.providerId} className={getClassName("kcFormSocialAccountListLinkClass")}>
<a href={p.loginUrl} id={`zocial-${p.alias}`} className={clsx("zocial", p.providerId)}>
<span>{p.displayName}</span>
</a>
</li>
))}
</ul>
</div>
)}
</div>
</Template>
); );
} }

View File

@ -23,159 +23,130 @@ export default function LoginConfigTotp(props: PageProps<Extract<KcContext, { pa
}; };
return ( return (
<Template <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} headerNode={msg("loginTotpTitle")}>
{...{ kcContext, i18n, doUseDefaultCss, classes }} <>
headerNode={msg("loginTotpTitle")} <ol id="kc-totp-settings">
formNode={ <li>
<> <p>{msg("loginTotpStep1")}</p>
<ol id="kc-totp-settings">
<li>
<p>{msg("loginTotpStep1")}</p>
<ul id="kc-totp-supported-apps"> <ul id="kc-totp-supported-apps">
{totp.policy.supportedApplications.map(app => ( {totp.policy.supportedApplications.map(app => (
<li>{app}</li> <li>{app}</li>
))} ))}
</ul> </ul>
</li> </li>
{mode && mode == "manual" ? ( {mode && mode == "manual" ? (
<> <>
<li>
<p>{msg("loginTotpManualStep2")}</p>
<p>
<span id="kc-totp-secret-key">{totp.totpSecretEncoded}</span>
</p>
<p>
<a href={totp.qrUrl} id="mode-barcode">
{msg("loginTotpScanBarcode")}
</a>
</p>
</li>
<li>
<p>{msg("loginTotpManualStep3")}</p>
<p>
<ul>
<li id="kc-totp-type">
{msg("loginTotpType")}: {msg(`loginTotp.${totp.policy.type}`)}
</li>
<li id="kc-totp-algorithm">
{msg("loginTotpAlgorithm")}: {algToKeyUriAlg?.[totp.policy.algorithm] ?? totp.policy.algorithm}
</li>
<li id="kc-totp-digits">
{msg("loginTotpDigits")}: {totp.policy.digits}
</li>
{totp.policy.type === "totp" ? (
<li id="kc-totp-period">
{msg("loginTotpInterval")}: {totp.policy.period}
</li>
) : (
<li id="kc-totp-counter">
{msg("loginTotpCounter")}: {totp.policy.initialCounter}
</li>
)}
</ul>
</p>
</li>
</>
) : (
<li> <li>
<p>{msg("loginTotpStep2")}</p> <p>{msg("loginTotpManualStep2")}</p>
<img id="kc-totp-secret-qr-code" src={`data:image/png;base64, ${totp.totpSecretQrCode}`} alt="Figure: Barcode" />
<br />
<p> <p>
<a href={totp.manualUrl} id="mode-manual"> <span id="kc-totp-secret-key">{totp.totpSecretEncoded}</span>
{msg("loginTotpUnableToScan")} </p>
<p>
<a href={totp.qrUrl} id="mode-barcode">
{msg("loginTotpScanBarcode")}
</a> </a>
</p> </p>
</li> </li>
)} <li>
<p>{msg("loginTotpManualStep3")}</p>
<p>
<ul>
<li id="kc-totp-type">
{msg("loginTotpType")}: {msg(`loginTotp.${totp.policy.type}`)}
</li>
<li id="kc-totp-algorithm">
{msg("loginTotpAlgorithm")}: {algToKeyUriAlg?.[totp.policy.algorithm] ?? totp.policy.algorithm}
</li>
<li id="kc-totp-digits">
{msg("loginTotpDigits")}: {totp.policy.digits}
</li>
{totp.policy.type === "totp" ? (
<li id="kc-totp-period">
{msg("loginTotpInterval")}: {totp.policy.period}
</li>
) : (
<li id="kc-totp-counter">
{msg("loginTotpCounter")}: {totp.policy.initialCounter}
</li>
)}
</ul>
</p>
</li>
</>
) : (
<li> <li>
<p>{msg("loginTotpStep3")}</p> <p>{msg("loginTotpStep2")}</p>
<p>{msg("loginTotpStep3DeviceName")}</p> <img id="kc-totp-secret-qr-code" src={`data:image/png;base64, ${totp.totpSecretQrCode}`} alt="Figure: Barcode" />
<br />
<p>
<a href={totp.manualUrl} id="mode-manual">
{msg("loginTotpUnableToScan")}
</a>
</p>
</li> </li>
</ol> )}
<li>
<p>{msg("loginTotpStep3")}</p>
<p>{msg("loginTotpStep3DeviceName")}</p>
</li>
</ol>
<form action={url.loginAction} className={getClassName("kcFormClass")} id="kc-totp-settings-form" method="post"> <form action={url.loginAction} className={getClassName("kcFormClass")} id="kc-totp-settings-form" method="post">
<div className={getClassName("kcFormGroupClass")}> <div className={getClassName("kcFormGroupClass")}>
<div className={getClassName("kcInputWrapperClass")}> <div className={getClassName("kcInputWrapperClass")}>
<label htmlFor="totp" className={getClassName("kcLabelClass")}> <label htmlFor="totp" className={getClassName("kcLabelClass")}>
{msg("authenticatorCode")} {msg("authenticatorCode")}
</label>{" "} </label>{" "}
<span className="required">*</span> <span className="required">*</span>
</div>
<div className={getClassName("kcInputWrapperClass")}>
<input
type="text"
id="totp"
name="totp"
autoComplete="off"
className={getClassName("kcInputClass")}
aria-invalid={messagesPerField.existsError("totp")}
/>
{messagesPerField.existsError("totp") && (
<span id="input-error-otp-code" className={getClassName("kcInputErrorMessageClass")} aria-live="polite">
{messagesPerField.get("totp")}
</span>
)}
</div>
<input type="hidden" id="totpSecret" name="totpSecret" value={totp.totpSecret} />
{mode && <input type="hidden" id="mode" value={mode} />}
</div> </div>
<div className={getClassName("kcInputWrapperClass")}>
<input
type="text"
id="totp"
name="totp"
autoComplete="off"
className={getClassName("kcInputClass")}
aria-invalid={messagesPerField.existsError("totp")}
/>
<div className={getClassName("kcFormGroupClass")}> {messagesPerField.existsError("totp") && (
<div className={getClassName("kcInputWrapperClass")}> <span id="input-error-otp-code" className={getClassName("kcInputErrorMessageClass")} aria-live="polite">
<label htmlFor="userLabel" className={getClassName("kcLabelClass")}> {messagesPerField.get("totp")}
{msg("loginTotpDeviceName")} </span>
</label>{" "} )}
{totp.otpCredentials.length >= 1 && <span className="required">*</span>}
</div>
<div className={getClassName("kcInputWrapperClass")}>
<input
type="text"
id="userLabel"
name="userLabel"
autoComplete="off"
className={getClassName("kcInputClass")}
aria-invalid={messagesPerField.existsError("userLabel")}
/>
{messagesPerField.existsError("userLabel") && (
<span id="input-error-otp-label" className={getClassName("kcInputErrorMessageClass")} aria-live="polite">
{messagesPerField.get("userLabel")}
</span>
)}
</div>
</div> </div>
<input type="hidden" id="totpSecret" name="totpSecret" value={totp.totpSecret} />
{mode && <input type="hidden" id="mode" value={mode} />}
</div>
{isAppInitiatedAction ? ( <div className={getClassName("kcFormGroupClass")}>
<> <div className={getClassName("kcInputWrapperClass")}>
<input <label htmlFor="userLabel" className={getClassName("kcLabelClass")}>
type="submit" {msg("loginTotpDeviceName")}
className={clsx( </label>{" "}
getClassName("kcButtonClass"), {totp.otpCredentials.length >= 1 && <span className="required">*</span>}
getClassName("kcButtonPrimaryClass"), </div>
getClassName("kcButtonLargeClass") <div className={getClassName("kcInputWrapperClass")}>
)} <input
id="saveTOTPBtn" type="text"
value={msgStr("doSubmit")} id="userLabel"
/> name="userLabel"
<button autoComplete="off"
type="submit" className={getClassName("kcInputClass")}
className={clsx( aria-invalid={messagesPerField.existsError("userLabel")}
getClassName("kcButtonClass"), />
getClassName("kcButtonDefaultClass"), {messagesPerField.existsError("userLabel") && (
getClassName("kcButtonLargeClass"), <span id="input-error-otp-label" className={getClassName("kcInputErrorMessageClass")} aria-live="polite">
getClassName("kcButtonLargeClass") {messagesPerField.get("userLabel")}
)} </span>
id="cancelTOTPBtn" )}
name="cancel-aia" </div>
value="true" </div>
>
${msg("doCancel")} {isAppInitiatedAction ? (
</button> <>
</>
) : (
<input <input
type="submit" type="submit"
className={clsx( className={clsx(
@ -186,10 +157,31 @@ export default function LoginConfigTotp(props: PageProps<Extract<KcContext, { pa
id="saveTOTPBtn" id="saveTOTPBtn"
value={msgStr("doSubmit")} value={msgStr("doSubmit")}
/> />
)} <button
</form> type="submit"
</> className={clsx(
} getClassName("kcButtonClass"),
/> getClassName("kcButtonDefaultClass"),
getClassName("kcButtonLargeClass"),
getClassName("kcButtonLargeClass")
)}
id="cancelTOTPBtn"
name="cancel-aia"
value="true"
>
${msg("doCancel")}
</button>
</>
) : (
<input
type="submit"
className={clsx(getClassName("kcButtonClass"), getClassName("kcButtonPrimaryClass"), getClassName("kcButtonLargeClass"))}
id="saveTOTPBtn"
value={msgStr("doSubmit")}
/>
)}
</form>
</>
</Template>
); );
} }

View File

@ -17,43 +17,39 @@ export default function LoginIdpLinkConfirm(props: PageProps<Extract<KcContext,
const { msg } = i18n; const { msg } = i18n;
return ( return (
<Template <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} headerNode={msg("confirmLinkIdpTitle")}>
{...{ kcContext, i18n, doUseDefaultCss, classes }} <form id="kc-register-form" action={url.loginAction} method="post">
headerNode={msg("confirmLinkIdpTitle")} <div className={getClassName("kcFormGroupClass")}>
formNode={ <button
<form id="kc-register-form" action={url.loginAction} method="post"> type="submit"
<div className={getClassName("kcFormGroupClass")}> className={clsx(
<button getClassName("kcButtonClass"),
type="submit" getClassName("kcButtonDefaultClass"),
className={clsx( getClassName("kcButtonBlockClass"),
getClassName("kcButtonClass"), getClassName("kcButtonLargeClass")
getClassName("kcButtonDefaultClass"), )}
getClassName("kcButtonBlockClass"), name="submitAction"
getClassName("kcButtonLargeClass") id="updateProfile"
)} value="updateProfile"
name="submitAction" >
id="updateProfile" {msg("confirmLinkIdpReviewProfile")}
value="updateProfile" </button>
> <button
{msg("confirmLinkIdpReviewProfile")} type="submit"
</button> className={clsx(
<button getClassName("kcButtonClass"),
type="submit" getClassName("kcButtonDefaultClass"),
className={clsx( getClassName("kcButtonBlockClass"),
getClassName("kcButtonClass"), getClassName("kcButtonLargeClass")
getClassName("kcButtonDefaultClass"), )}
getClassName("kcButtonBlockClass"), name="submitAction"
getClassName("kcButtonLargeClass") id="linkAccount"
)} value="linkAccount"
name="submitAction" >
id="linkAccount" {msg("confirmLinkIdpContinue", idpAlias)}
value="linkAccount" </button>
> </div>
{msg("confirmLinkIdpContinue", idpAlias)} </form>
</button> </Template>
</div>
</form>
}
/>
); );
} }

View File

@ -10,22 +10,16 @@ export default function LoginIdpLinkEmail(props: PageProps<Extract<KcContext, {
const { msg } = i18n; const { msg } = i18n;
return ( return (
<Template <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} headerNode={msg("emailLinkIdpTitle", idpAlias)}>
{...{ kcContext, i18n, doUseDefaultCss, classes }} <p id="instruction1" className="instruction">
headerNode={msg("emailLinkIdpTitle", idpAlias)} {msg("emailLinkIdp1", idpAlias, brokerContext.username, realm.displayName)}
formNode={ </p>
<> <p id="instruction2" className="instruction">
<p id="instruction1" className="instruction"> {msg("emailLinkIdp2")} <a href={url.loginAction}>{msg("doClickHere")}</a> {msg("emailLinkIdp3")}
{msg("emailLinkIdp1", idpAlias, brokerContext.username, realm.displayName)} </p>
</p> <p id="instruction3" className="instruction">
<p id="instruction2" className="instruction"> {msg("emailLinkIdp4")} <a href={url.loginAction}>{msg("doClickHere")}</a> {msg("emailLinkIdp5")}
{msg("emailLinkIdp2")} <a href={url.loginAction}>{msg("doClickHere")}</a> {msg("emailLinkIdp3")} </p>
</p> </Template>
<p id="instruction3" className="instruction">
{msg("emailLinkIdp4")} <a href={url.loginAction}>{msg("doClickHere")}</a> {msg("emailLinkIdp5")}
</p>
</>
}
/>
); );
} }

View File

@ -37,61 +37,57 @@ export default function LoginOtp(props: PageProps<Extract<KcContext, { pageId: "
}, []); }, []);
return ( return (
<Template <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} headerNode={msg("doLogIn")}>
{...{ kcContext, i18n, doUseDefaultCss, classes }} <form id="kc-otp-login-form" className={getClassName("kcFormClass")} action={url.loginAction} method="post">
headerNode={msg("doLogIn")} {otpLogin.userOtpCredentials.length > 1 && (
formNode={
<form id="kc-otp-login-form" className={getClassName("kcFormClass")} action={url.loginAction} method="post">
{otpLogin.userOtpCredentials.length > 1 && (
<div className={getClassName("kcFormGroupClass")}>
<div className={getClassName("kcInputWrapperClass")}>
{otpLogin.userOtpCredentials.map(otpCredential => (
<div key={otpCredential.id} className={getClassName("kcSelectOTPListClass")}>
<input type="hidden" value="${otpCredential.id}" />
<div className={getClassName("kcSelectOTPListItemClass")}>
<span className={getClassName("kcAuthenticatorOtpCircleClass")} />
<h2 className={getClassName("kcSelectOTPItemHeadingClass")}>{otpCredential.userLabel}</h2>
</div>
</div>
))}
</div>
</div>
)}
<div className={getClassName("kcFormGroupClass")}> <div className={getClassName("kcFormGroupClass")}>
<div className={getClassName("kcLabelWrapperClass")}>
<label htmlFor="otp" className={getClassName("kcLabelClass")}>
{msg("loginOtpOneTime")}
</label>
</div>
<div className={getClassName("kcInputWrapperClass")}> <div className={getClassName("kcInputWrapperClass")}>
<input id="otp" name="otp" autoComplete="off" type="text" className={getClassName("kcInputClass")} autoFocus /> {otpLogin.userOtpCredentials.map(otpCredential => (
<div key={otpCredential.id} className={getClassName("kcSelectOTPListClass")}>
<input type="hidden" value="${otpCredential.id}" />
<div className={getClassName("kcSelectOTPListItemClass")}>
<span className={getClassName("kcAuthenticatorOtpCircleClass")} />
<h2 className={getClassName("kcSelectOTPItemHeadingClass")}>{otpCredential.userLabel}</h2>
</div>
</div>
))}
</div> </div>
</div> </div>
)}
<div className={getClassName("kcFormGroupClass")}> <div className={getClassName("kcFormGroupClass")}>
<div id="kc-form-options" className={getClassName("kcFormOptionsClass")}> <div className={getClassName("kcLabelWrapperClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")} /> <label htmlFor="otp" className={getClassName("kcLabelClass")}>
</div> {msg("loginOtpOneTime")}
</label>
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
name="login"
id="kc-login"
type="submit"
value={msgStr("doLogIn")}
/>
</div>
</div> </div>
</form>
} <div className={getClassName("kcInputWrapperClass")}>
/> <input id="otp" name="otp" autoComplete="off" type="text" className={getClassName("kcInputClass")} autoFocus />
</div>
</div>
<div className={getClassName("kcFormGroupClass")}>
<div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")} />
</div>
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
name="login"
id="kc-login"
type="submit"
value={msgStr("doLogIn")}
/>
</div>
</div>
</form>
</Template>
); );
} }

View File

@ -10,26 +10,19 @@ export default function LoginPageExpired(props: PageProps<Extract<KcContext, { p
const { msg } = i18n; const { msg } = i18n;
return ( return (
<Template <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} displayMessage={false} headerNode={msg("pageExpiredTitle")}>
{...{ kcContext, i18n, doUseDefaultCss, classes }} <p id="instruction1" className="instruction">
displayMessage={false} {msg("pageExpiredMsg1")}
headerNode={msg("pageExpiredTitle")} <a id="loginRestartLink" href={url.loginRestartFlowUrl}>
formNode={ {msg("doClickHere")}
<> </a>{" "}
<p id="instruction1" className="instruction"> .<br />
{msg("pageExpiredMsg1")} {msg("pageExpiredMsg2")}{" "}
<a id="loginRestartLink" href={url.loginRestartFlowUrl}> <a id="loginContinueLink" href={url.loginAction}>
{msg("doClickHere")} {msg("doClickHere")}
</a>{" "} </a>{" "}
.<br /> .
{msg("pageExpiredMsg2")}{" "} </p>
<a id="loginContinueLink" href={url.loginAction}> </Template>
{msg("doClickHere")}
</a>{" "}
.
</p>
</>
}
/>
); );
} }

View File

@ -32,61 +32,57 @@ export default function LoginPassword(props: PageProps<Extract<KcContext, { "pag
}); });
return ( return (
<Template <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} headerNode={msg("doLogIn")}>
{...{ kcContext, i18n, doUseDefaultCss, classes }} <div id="kc-form">
headerNode={msg("doLogIn")} <div id="kc-form-wrapper">
formNode={ <form id="kc-form-login" onSubmit={onSubmit} action={url.loginAction} method="post">
<div id="kc-form"> <div className={getClassName("kcFormGroupClass")}>
<div id="kc-form-wrapper"> <hr />
<form id="kc-form-login" onSubmit={onSubmit} action={url.loginAction} method="post"> <label htmlFor="password" className={getClassName("kcLabelClass")}>
<div className={getClassName("kcFormGroupClass")}> {msg("password")}
<hr /> </label>
<label htmlFor="password" className={getClassName("kcLabelClass")}> <input
{msg("password")} tabIndex={2}
</label> id="password"
<input className={getClassName("kcInputClass")}
tabIndex={2} name="password"
id="password" type="password"
className={getClassName("kcInputClass")} autoFocus={true}
name="password" autoComplete="on"
type="password" defaultValue={login.password ?? ""}
autoFocus={true} />
autoComplete="on" </div>
defaultValue={login.password ?? ""} <div className={clsx(getClassName("kcFormGroupClass"), getClassName("kcFormSettingClass"))}>
/> <div id="kc-form-options" />
<div className={getClassName("kcFormOptionsWrapperClass")}>
{realm.resetPasswordAllowed && (
<span>
<a tabIndex={5} href={url.loginResetCredentialsUrl}>
{msg("doForgotPassword")}
</a>
</span>
)}
</div> </div>
<div className={clsx(getClassName("kcFormGroupClass"), getClassName("kcFormSettingClass"))}> </div>
<div id="kc-form-options" /> <div id="kc-form-buttons" className={getClassName("kcFormGroupClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")}> <input
{realm.resetPasswordAllowed && ( tabIndex={4}
<span> className={clsx(
<a tabIndex={5} href={url.loginResetCredentialsUrl}> getClassName("kcButtonClass"),
{msg("doForgotPassword")} getClassName("kcButtonPrimaryClass"),
</a> getClassName("kcButtonBlockClass"),
</span> getClassName("kcButtonLargeClass")
)} )}
</div> name="login"
</div> id="kc-login"
<div id="kc-form-buttons" className={getClassName("kcFormGroupClass")}> type="submit"
<input value={msgStr("doLogIn")}
tabIndex={4} disabled={isLoginButtonDisabled}
className={clsx( />
getClassName("kcButtonClass"), </div>
getClassName("kcButtonPrimaryClass"), </form>
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
name="login"
id="kc-login"
type="submit"
value={msgStr("doLogIn")}
disabled={isLoginButtonDisabled}
/>
</div>
</form>
</div>
</div> </div>
} </div>
/> </Template>
); );
} }

View File

@ -21,54 +21,53 @@ export default function LoginResetPassword(props: PageProps<Extract<KcContext, {
{...{ kcContext, i18n, doUseDefaultCss, classes }} {...{ kcContext, i18n, doUseDefaultCss, classes }}
displayMessage={false} displayMessage={false}
headerNode={msg("emailForgotTitle")} headerNode={msg("emailForgotTitle")}
formNode={
<form id="kc-reset-password-form" className={getClassName("kcFormClass")} action={url.loginAction} method="post">
<div className={getClassName("kcFormGroupClass")}>
<div className={getClassName("kcLabelWrapperClass")}>
<label htmlFor="username" className={getClassName("kcLabelClass")}>
{!realm.loginWithEmailAllowed
? msg("username")
: !realm.registrationEmailAsUsername
? msg("usernameOrEmail")
: msg("email")}
</label>
</div>
<div className={getClassName("kcInputWrapperClass")}>
<input
type="text"
id="username"
name="username"
className={getClassName("kcInputClass")}
autoFocus
defaultValue={auth !== undefined && auth.showUsername ? auth.attemptedUsername : undefined}
/>
</div>
</div>
<div className={clsx(getClassName("kcFormGroupClass"), getClassName("kcFormSettingClass"))}>
<div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")}>
<span>
<a href={url.loginUrl}>{msg("backToLogin")}</a>
</span>
</div>
</div>
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
type="submit"
value={msgStr("doSubmit")}
/>
</div>
</div>
</form>
}
infoNode={msg("emailInstruction")} infoNode={msg("emailInstruction")}
/> >
<form id="kc-reset-password-form" className={getClassName("kcFormClass")} action={url.loginAction} method="post">
<div className={getClassName("kcFormGroupClass")}>
<div className={getClassName("kcLabelWrapperClass")}>
<label htmlFor="username" className={getClassName("kcLabelClass")}>
{!realm.loginWithEmailAllowed
? msg("username")
: !realm.registrationEmailAsUsername
? msg("usernameOrEmail")
: msg("email")}
</label>
</div>
<div className={getClassName("kcInputWrapperClass")}>
<input
type="text"
id="username"
name="username"
className={getClassName("kcInputClass")}
autoFocus
defaultValue={auth !== undefined && auth.showUsername ? auth.attemptedUsername : undefined}
/>
</div>
</div>
<div className={clsx(getClassName("kcFormGroupClass"), getClassName("kcFormSettingClass"))}>
<div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")}>
<span>
<a href={url.loginUrl}>{msg("backToLogin")}</a>
</span>
</div>
</div>
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
type="submit"
value={msgStr("doSubmit")}
/>
</div>
</div>
</form>
</Template>
); );
} }

View File

@ -17,122 +17,118 @@ export default function LoginUpdatePassword(props: PageProps<Extract<KcContext,
const { url, messagesPerField, isAppInitiatedAction, username } = kcContext; const { url, messagesPerField, isAppInitiatedAction, username } = kcContext;
return ( return (
<Template <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} headerNode={msg("updatePasswordTitle")}>
{...{ kcContext, i18n, doUseDefaultCss, classes }} <form id="kc-passwd-update-form" className={getClassName("kcFormClass")} action={url.loginAction} method="post">
headerNode={msg("updatePasswordTitle")} <input
formNode={ type="text"
<form id="kc-passwd-update-form" className={getClassName("kcFormClass")} action={url.loginAction} method="post"> id="username"
<input name="username"
type="text" value={username}
id="username" readOnly={true}
name="username" autoComplete="username"
value={username} style={{ display: "none" }}
readOnly={true} />
autoComplete="username" <input type="password" id="password" name="password" autoComplete="current-password" style={{ display: "none" }} />
style={{ display: "none" }}
/>
<input type="password" id="password" name="password" autoComplete="current-password" style={{ display: "none" }} />
<div <div
className={clsx( className={clsx(
getClassName("kcFormGroupClass"), getClassName("kcFormGroupClass"),
messagesPerField.printIfExists("password", getClassName("kcFormGroupErrorClass")) messagesPerField.printIfExists("password", getClassName("kcFormGroupErrorClass"))
)} )}
> >
<div className={getClassName("kcLabelWrapperClass")}> <div className={getClassName("kcLabelWrapperClass")}>
<label htmlFor="password-new" className={getClassName("kcLabelClass")}> <label htmlFor="password-new" className={getClassName("kcLabelClass")}>
{msg("passwordNew")} {msg("passwordNew")}
</label> </label>
</div> </div>
<div className={getClassName("kcInputWrapperClass")}> <div className={getClassName("kcInputWrapperClass")}>
<input <input
type="password" type="password"
id="password-new" id="password-new"
name="password-new" name="password-new"
autoFocus autoFocus
autoComplete="new-password" autoComplete="new-password"
className={getClassName("kcInputClass")} className={getClassName("kcInputClass")}
/> />
</div>
</div>
<div
className={clsx(
getClassName("kcFormGroupClass"),
messagesPerField.printIfExists("password-confirm", getClassName("kcFormGroupErrorClass"))
)}
>
<div className={getClassName("kcLabelWrapperClass")}>
<label htmlFor="password-confirm" className={getClassName("kcLabelClass")}>
{msg("passwordConfirm")}
</label>
</div>
<div className={getClassName("kcInputWrapperClass")}>
<input
type="password"
id="password-confirm"
name="password-confirm"
autoComplete="new-password"
className={getClassName("kcInputClass")}
/>
</div>
</div>
<div className={getClassName("kcFormGroupClass")}>
<div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")}>
{isAppInitiatedAction && (
<div className="checkbox">
<label>
<input type="checkbox" id="logout-sessions" name="logout-sessions" value="on" checked />
{msgStr("logoutOtherSessions")}
</label>
</div>
)}
</div> </div>
</div> </div>
<div <div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
className={clsx( {isAppInitiatedAction ? (
getClassName("kcFormGroupClass"), <>
messagesPerField.printIfExists("password-confirm", getClassName("kcFormGroupErrorClass"))
)}
>
<div className={getClassName("kcLabelWrapperClass")}>
<label htmlFor="password-confirm" className={getClassName("kcLabelClass")}>
{msg("passwordConfirm")}
</label>
</div>
<div className={getClassName("kcInputWrapperClass")}>
<input
type="password"
id="password-confirm"
name="password-confirm"
autoComplete="new-password"
className={getClassName("kcInputClass")}
/>
</div>
</div>
<div className={getClassName("kcFormGroupClass")}>
<div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")}>
{isAppInitiatedAction && (
<div className="checkbox">
<label>
<input type="checkbox" id="logout-sessions" name="logout-sessions" value="on" checked />
{msgStr("logoutOtherSessions")}
</label>
</div>
)}
</div>
</div>
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
{isAppInitiatedAction ? (
<>
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonLargeClass")
)}
type="submit"
defaultValue={msgStr("doSubmit")}
/>
<button
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonDefaultClass"),
getClassName("kcButtonLargeClass")
)}
type="submit"
name="cancel-aia"
value="true"
>
{msg("doCancel")}
</button>
</>
) : (
<input <input
className={clsx( className={clsx(
getClassName("kcButtonClass"), getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"), getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass") getClassName("kcButtonLargeClass")
)} )}
type="submit" type="submit"
defaultValue={msgStr("doSubmit")} defaultValue={msgStr("doSubmit")}
/> />
)} <button
</div> className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonDefaultClass"),
getClassName("kcButtonLargeClass")
)}
type="submit"
name="cancel-aia"
value="true"
>
{msg("doCancel")}
</button>
</>
) : (
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
type="submit"
defaultValue={msgStr("doSubmit")}
/>
)}
</div> </div>
</form> </div>
} </form>
/> </Template>
); );
} }

View File

@ -17,141 +17,134 @@ export default function LoginUpdateProfile(props: PageProps<Extract<KcContext, {
const { url, user, messagesPerField, isAppInitiatedAction } = kcContext; const { url, user, messagesPerField, isAppInitiatedAction } = kcContext;
return ( return (
<Template <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} headerNode={msg("loginProfileTitle")}>
{...{ kcContext, i18n, doUseDefaultCss, classes }} <form id="kc-update-profile-form" className={getClassName("kcFormClass")} action={url.loginAction} method="post">
headerNode={msg("loginProfileTitle")} {user.editUsernameAllowed && (
formNode={ <div
<form id="kc-update-profile-form" className={getClassName("kcFormClass")} action={url.loginAction} method="post"> className={clsx(
{user.editUsernameAllowed && ( getClassName("kcFormGroupClass"),
<div messagesPerField.printIfExists("username", getClassName("kcFormGroupErrorClass"))
className={clsx( )}
getClassName("kcFormGroupClass"), >
messagesPerField.printIfExists("username", getClassName("kcFormGroupErrorClass")) <div className={getClassName("kcLabelWrapperClass")}>
)} <label htmlFor="username" className={getClassName("kcLabelClass")}>
> {msg("username")}
<div className={getClassName("kcLabelWrapperClass")}> </label>
<label htmlFor="username" className={getClassName("kcLabelClass")}>
{msg("username")}
</label>
</div>
<div className={getClassName("kcInputWrapperClass")}>
<input
type="text"
id="username"
name="username"
defaultValue={user.username ?? ""}
className={getClassName("kcInputClass")}
/>
</div>
</div> </div>
<div className={getClassName("kcInputWrapperClass")}>
<input
type="text"
id="username"
name="username"
defaultValue={user.username ?? ""}
className={getClassName("kcInputClass")}
/>
</div>
</div>
)}
<div
className={clsx(getClassName("kcFormGroupClass"), messagesPerField.printIfExists("email", getClassName("kcFormGroupErrorClass")))}
>
<div className={getClassName("kcLabelWrapperClass")}>
<label htmlFor="email" className={getClassName("kcLabelClass")}>
{msg("email")}
</label>
</div>
<div className={getClassName("kcInputWrapperClass")}>
<input type="text" id="email" name="email" defaultValue={user.email ?? ""} className={getClassName("kcInputClass")} />
</div>
</div>
<div
className={clsx(
getClassName("kcFormGroupClass"),
messagesPerField.printIfExists("firstName", getClassName("kcFormGroupErrorClass"))
)} )}
>
<div className={getClassName("kcLabelWrapperClass")}>
<label htmlFor="firstName" className={getClassName("kcLabelClass")}>
{msg("firstName")}
</label>
</div>
<div className={getClassName("kcInputWrapperClass")}>
<input
type="text"
id="firstName"
name="firstName"
defaultValue={user.firstName ?? ""}
className={getClassName("kcInputClass")}
/>
</div>
</div>
<div <div
className={clsx( className={clsx(
getClassName("kcFormGroupClass"), getClassName("kcFormGroupClass"),
messagesPerField.printIfExists("email", getClassName("kcFormGroupErrorClass")) messagesPerField.printIfExists("lastName", getClassName("kcFormGroupErrorClass"))
)} )}
> >
<div className={getClassName("kcLabelWrapperClass")}> <div className={getClassName("kcLabelWrapperClass")}>
<label htmlFor="email" className={getClassName("kcLabelClass")}> <label htmlFor="lastName" className={getClassName("kcLabelClass")}>
{msg("email")} {msg("lastName")}
</label> </label>
</div> </div>
<div className={getClassName("kcInputWrapperClass")}> <div className={getClassName("kcInputWrapperClass")}>
<input type="text" id="email" name="email" defaultValue={user.email ?? ""} className={getClassName("kcInputClass")} /> <input
</div> type="text"
id="lastName"
name="lastName"
defaultValue={user.lastName ?? ""}
className={getClassName("kcInputClass")}
/>
</div>
</div>
<div className={getClassName("kcFormGroupClass")}>
<div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")} />
</div> </div>
<div <div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
className={clsx( {isAppInitiatedAction ? (
getClassName("kcFormGroupClass"), <>
messagesPerField.printIfExists("firstName", getClassName("kcFormGroupErrorClass"))
)}
>
<div className={getClassName("kcLabelWrapperClass")}>
<label htmlFor="firstName" className={getClassName("kcLabelClass")}>
{msg("firstName")}
</label>
</div>
<div className={getClassName("kcInputWrapperClass")}>
<input
type="text"
id="firstName"
name="firstName"
defaultValue={user.firstName ?? ""}
className={getClassName("kcInputClass")}
/>
</div>
</div>
<div
className={clsx(
getClassName("kcFormGroupClass"),
messagesPerField.printIfExists("lastName", getClassName("kcFormGroupErrorClass"))
)}
>
<div className={getClassName("kcLabelWrapperClass")}>
<label htmlFor="lastName" className={getClassName("kcLabelClass")}>
{msg("lastName")}
</label>
</div>
<div className={getClassName("kcInputWrapperClass")}>
<input
type="text"
id="lastName"
name="lastName"
defaultValue={user.lastName ?? ""}
className={getClassName("kcInputClass")}
/>
</div>
</div>
<div className={getClassName("kcFormGroupClass")}>
<div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")} />
</div>
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
{isAppInitiatedAction ? (
<>
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonLargeClass")
)}
type="submit"
defaultValue={msgStr("doSubmit")}
/>
<button
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonDefaultClass"),
getClassName("kcButtonLargeClass")
)}
type="submit"
name="cancel-aia"
value="true"
>
{msg("doCancel")}
</button>
</>
) : (
<input <input
className={clsx( className={clsx(
getClassName("kcButtonClass"), getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"), getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass") getClassName("kcButtonLargeClass")
)} )}
type="submit" type="submit"
defaultValue={msgStr("doSubmit")} defaultValue={msgStr("doSubmit")}
/> />
)} <button
</div> className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonDefaultClass"),
getClassName("kcButtonLargeClass")
)}
type="submit"
name="cancel-aia"
value="true"
>
{msg("doCancel")}
</button>
</>
) : (
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
type="submit"
defaultValue={msgStr("doSubmit")}
/>
)}
</div> </div>
</form> </div>
} </form>
/> </Template>
); );
} }

View File

@ -41,114 +41,6 @@ export default function LoginUsername(props: PageProps<Extract<KcContext, { page
displayInfo={social.displayInfo} displayInfo={social.displayInfo}
displayWide={realm.password && social.providers !== undefined} displayWide={realm.password && social.providers !== undefined}
headerNode={msg("doLogIn")} headerNode={msg("doLogIn")}
formNode={
<div id="kc-form" className={clsx(realm.password && social.providers !== undefined && getClassName("kcContentWrapperClass"))}>
<div
id="kc-form-wrapper"
className={clsx(
realm.password &&
social.providers && [getClassName("kcFormSocialAccountContentClass"), getClassName("kcFormSocialAccountClass")]
)}
>
{realm.password && (
<form id="kc-form-login" onSubmit={onSubmit} action={url.loginAction} method="post">
<div className={getClassName("kcFormGroupClass")}>
{!usernameHidden &&
(() => {
const label = !realm.loginWithEmailAllowed
? "username"
: realm.registrationEmailAsUsername
? "email"
: "usernameOrEmail";
const autoCompleteHelper: typeof label = label === "usernameOrEmail" ? "username" : label;
return (
<>
<label htmlFor={autoCompleteHelper} className={getClassName("kcLabelClass")}>
{msg(label)}
</label>
<input
tabIndex={1}
id={autoCompleteHelper}
className={getClassName("kcInputClass")}
//NOTE: This is used by Google Chrome auto fill so we use it to tell
//the browser how to pre fill the form but before submit we put it back
//to username because it is what keycloak expects.
name={autoCompleteHelper}
defaultValue={login.username ?? ""}
type="text"
autoFocus={true}
autoComplete="off"
/>
</>
);
})()}
</div>
<div className={clsx(getClassName("kcFormGroupClass"), getClassName("kcFormSettingClass"))}>
<div id="kc-form-options">
{realm.rememberMe && !usernameHidden && (
<div className="checkbox">
<label>
<input
tabIndex={3}
id="rememberMe"
name="rememberMe"
type="checkbox"
{...(login.rememberMe
? {
"checked": true
}
: {})}
/>
{msg("rememberMe")}
</label>
</div>
)}
</div>
</div>
<div id="kc-form-buttons" className={getClassName("kcFormGroupClass")}>
<input
tabIndex={4}
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
name="login"
id="kc-login"
type="submit"
value={msgStr("doLogIn")}
disabled={isLoginButtonDisabled}
/>
</div>
</form>
)}
</div>
{realm.password && social.providers !== undefined && (
<div
id="kc-social-providers"
className={clsx(getClassName("kcFormSocialAccountContentClass"), getClassName("kcFormSocialAccountClass"))}
>
<ul
className={clsx(
getClassName("kcFormSocialAccountListClass"),
social.providers.length > 4 && getClassName("kcFormSocialAccountDoubleListClass")
)}
>
{social.providers.map(p => (
<li key={p.providerId} className={getClassName("kcFormSocialAccountListLinkClass")}>
<a href={p.loginUrl} id={`zocial-${p.alias}`} className={clsx("zocial", p.providerId)}>
<span>{p.displayName}</span>
</a>
</li>
))}
</ul>
</div>
)}
</div>
}
infoNode={ infoNode={
realm.password && realm.password &&
realm.registrationAllowed && realm.registrationAllowed &&
@ -163,6 +55,113 @@ export default function LoginUsername(props: PageProps<Extract<KcContext, { page
</div> </div>
) )
} }
/> >
<div id="kc-form" className={clsx(realm.password && social.providers !== undefined && getClassName("kcContentWrapperClass"))}>
<div
id="kc-form-wrapper"
className={clsx(
realm.password &&
social.providers && [getClassName("kcFormSocialAccountContentClass"), getClassName("kcFormSocialAccountClass")]
)}
>
{realm.password && (
<form id="kc-form-login" onSubmit={onSubmit} action={url.loginAction} method="post">
<div className={getClassName("kcFormGroupClass")}>
{!usernameHidden &&
(() => {
const label = !realm.loginWithEmailAllowed
? "username"
: realm.registrationEmailAsUsername
? "email"
: "usernameOrEmail";
const autoCompleteHelper: typeof label = label === "usernameOrEmail" ? "username" : label;
return (
<>
<label htmlFor={autoCompleteHelper} className={getClassName("kcLabelClass")}>
{msg(label)}
</label>
<input
tabIndex={1}
id={autoCompleteHelper}
className={getClassName("kcInputClass")}
//NOTE: This is used by Google Chrome auto fill so we use it to tell
//the browser how to pre fill the form but before submit we put it back
//to username because it is what keycloak expects.
name={autoCompleteHelper}
defaultValue={login.username ?? ""}
type="text"
autoFocus={true}
autoComplete="off"
/>
</>
);
})()}
</div>
<div className={clsx(getClassName("kcFormGroupClass"), getClassName("kcFormSettingClass"))}>
<div id="kc-form-options">
{realm.rememberMe && !usernameHidden && (
<div className="checkbox">
<label>
<input
tabIndex={3}
id="rememberMe"
name="rememberMe"
type="checkbox"
{...(login.rememberMe
? {
"checked": true
}
: {})}
/>
{msg("rememberMe")}
</label>
</div>
)}
</div>
</div>
<div id="kc-form-buttons" className={getClassName("kcFormGroupClass")}>
<input
tabIndex={4}
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
name="login"
id="kc-login"
type="submit"
value={msgStr("doLogIn")}
disabled={isLoginButtonDisabled}
/>
</div>
</form>
)}
</div>
{realm.password && social.providers !== undefined && (
<div
id="kc-social-providers"
className={clsx(getClassName("kcFormSocialAccountContentClass"), getClassName("kcFormSocialAccountClass"))}
>
<ul
className={clsx(
getClassName("kcFormSocialAccountListClass"),
social.providers.length > 4 && getClassName("kcFormSocialAccountDoubleListClass")
)}
>
{social.providers.map(p => (
<li key={p.providerId} className={getClassName("kcFormSocialAccountListLinkClass")}>
<a href={p.loginUrl} id={`zocial-${p.alias}`} className={clsx("zocial", p.providerId)}>
<span>{p.displayName}</span>
</a>
</li>
))}
</ul>
</div>
)}
</div>
</Template>
); );
} }

View File

@ -10,22 +10,15 @@ export default function LoginVerifyEmail(props: PageProps<Extract<KcContext, { p
const { url, user } = kcContext; const { url, user } = kcContext;
return ( return (
<Template <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} displayMessage={false} headerNode={msg("emailVerifyTitle")}>
{...{ kcContext, i18n, doUseDefaultCss, classes }} <p className="instruction">{msg("emailVerifyInstruction1", user?.email)}</p>
displayMessage={false} <p className="instruction">
headerNode={msg("emailVerifyTitle")} {msg("emailVerifyInstruction2")}
formNode={ <br />
<> <a href={url.loginAction}>{msg("doClickHere")}</a>
<p className="instruction">{msg("emailVerifyInstruction1", user?.email)}</p> &nbsp;
<p className="instruction"> {msg("emailVerifyInstruction3")}
{msg("emailVerifyInstruction2")} </p>
<br /> </Template>
<a href={url.loginAction}>{msg("doClickHere")}</a>
&nbsp;
{msg("emailVerifyInstruction3")}
</p>
</>
}
/>
); );
} }

View File

@ -17,47 +17,40 @@ export default function LogoutConfirm(props: PageProps<Extract<KcContext, { page
const { msg, msgStr } = i18n; const { msg, msgStr } = i18n;
return ( return (
<Template <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} displayMessage={false} headerNode={msg("logoutConfirmTitle")}>
{...{ kcContext, i18n, doUseDefaultCss, classes }} <div id="kc-logout-confirm" className="content-area">
displayMessage={false} <p className="instruction">{msg("logoutConfirmHeader")}</p>
headerNode={msg("logoutConfirmTitle")} <form className="form-actions" action={url.logoutConfirmAction} method="POST">
formNode={ <input type="hidden" name="session_code" value={logoutConfirm.code} />
<> <div className={getClassName("kcFormGroupClass")}>
<div id="kc-logout-confirm" className="content-area"> <div id="kc-form-options">
<p className="instruction">{msg("logoutConfirmHeader")}</p> <div className={getClassName("kcFormOptionsWrapperClass")}></div>
<form className="form-actions" action={url.logoutConfirmAction} method="POST"> </div>
<input type="hidden" name="session_code" value={logoutConfirm.code} /> <div id="kc-form-buttons" className={getClassName("kcFormGroupClass")}>
<div className={getClassName("kcFormGroupClass")}> <input
<div id="kc-form-options"> tabIndex={4}
<div className={getClassName("kcFormOptionsWrapperClass")}></div> className={clsx(
</div> getClassName("kcButtonClass"),
<div id="kc-form-buttons" className={getClassName("kcFormGroupClass")}> getClassName("kcButtonPrimaryClass"),
<input getClassName("kcButtonBlockClass"),
tabIndex={4} getClassName("kcButtonLargeClass")
className={clsx( )}
getClassName("kcButtonClass"), name="confirmLogout"
getClassName("kcButtonPrimaryClass"), id="kc-logout"
getClassName("kcButtonBlockClass"), type="submit"
getClassName("kcButtonLargeClass") value={msgStr("doLogout")}
)} />
name="confirmLogout"
id="kc-logout"
type="submit"
value={msgStr("doLogout")}
/>
</div>
</div>
</form>
<div id="kc-info-message">
{!logoutConfirm.skipLink && client.baseUrl && (
<p>
<a href={client.baseUrl} dangerouslySetInnerHTML={{ __html: msgStr("backToApplication") }} />
</p>
)}
</div> </div>
</div> </div>
</> </form>
} <div id="kc-info-message">
/> {!logoutConfirm.skipLink && client.baseUrl && (
<p>
<a href={client.baseUrl} dangerouslySetInnerHTML={{ __html: msgStr("backToApplication") }} />
</p>
)}
</div>
</div>
</Template>
); );
} }

View File

@ -17,173 +17,166 @@ export default function Register(props: PageProps<Extract<KcContext, { pageId: "
const { msg, msgStr } = i18n; const { msg, msgStr } = i18n;
return ( return (
<Template <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} headerNode={msg("registerTitle")}>
{...{ kcContext, i18n, doUseDefaultCss, classes }} <form id="kc-register-form" className={getClassName("kcFormClass")} action={url.registrationAction} method="post">
headerNode={msg("registerTitle")} <div
formNode={ className={clsx(
<form id="kc-register-form" className={getClassName("kcFormClass")} action={url.registrationAction} method="post"> getClassName("kcFormGroupClass"),
<div messagesPerField.printIfExists("firstName", getClassName("kcFormGroupErrorClass"))
className={clsx( )}
getClassName("kcFormGroupClass"), >
messagesPerField.printIfExists("firstName", getClassName("kcFormGroupErrorClass")) <div className={getClassName("kcLabelWrapperClass")}>
)} <label htmlFor="firstName" className={getClassName("kcLabelClass")}>
> {msg("firstName")}
<div className={getClassName("kcLabelWrapperClass")}> </label>
<label htmlFor="firstName" className={getClassName("kcLabelClass")}>
{msg("firstName")}
</label>
</div>
<div className={getClassName("kcInputWrapperClass")}>
<input
type="text"
id="firstName"
className={getClassName("kcInputClass")}
name="firstName"
defaultValue={register.formData.firstName ?? ""}
/>
</div>
</div> </div>
<div className={getClassName("kcInputWrapperClass")}>
<input
type="text"
id="firstName"
className={getClassName("kcInputClass")}
name="firstName"
defaultValue={register.formData.firstName ?? ""}
/>
</div>
</div>
<div <div
className={clsx( className={clsx(
getClassName("kcFormGroupClass"), getClassName("kcFormGroupClass"),
messagesPerField.printIfExists("lastName", getClassName("kcFormGroupErrorClass")) messagesPerField.printIfExists("lastName", getClassName("kcFormGroupErrorClass"))
)} )}
> >
<div className={getClassName("kcLabelWrapperClass")}> <div className={getClassName("kcLabelWrapperClass")}>
<label htmlFor="lastName" className={getClassName("kcLabelClass")}> <label htmlFor="lastName" className={getClassName("kcLabelClass")}>
{msg("lastName")} {msg("lastName")}
</label> </label>
</div>
<div className={getClassName("kcInputWrapperClass")}>
<input
type="text"
id="lastName"
className={getClassName("kcInputClass")}
name="lastName"
defaultValue={register.formData.lastName ?? ""}
/>
</div>
</div> </div>
<div className={getClassName("kcInputWrapperClass")}>
<input
type="text"
id="lastName"
className={getClassName("kcInputClass")}
name="lastName"
defaultValue={register.formData.lastName ?? ""}
/>
</div>
</div>
<div
className={clsx(getClassName("kcFormGroupClass"), messagesPerField.printIfExists("email", getClassName("kcFormGroupErrorClass")))}
>
<div className={getClassName("kcLabelWrapperClass")}>
<label htmlFor="email" className={getClassName("kcLabelClass")}>
{msg("email")}
</label>
</div>
<div className={getClassName("kcInputWrapperClass")}>
<input
type="text"
id="email"
className={getClassName("kcInputClass")}
name="email"
defaultValue={register.formData.email ?? ""}
autoComplete="email"
/>
</div>
</div>
{!realm.registrationEmailAsUsername && (
<div <div
className={clsx( className={clsx(
getClassName("kcFormGroupClass"), getClassName("kcFormGroupClass"),
messagesPerField.printIfExists("email", getClassName("kcFormGroupErrorClass")) messagesPerField.printIfExists("username", getClassName("kcFormGroupErrorClass"))
)} )}
> >
<div className={getClassName("kcLabelWrapperClass")}> <div className={getClassName("kcLabelWrapperClass")}>
<label htmlFor="email" className={getClassName("kcLabelClass")}> <label htmlFor="username" className={getClassName("kcLabelClass")}>
{msg("email")} {msg("username")}
</label> </label>
</div> </div>
<div className={getClassName("kcInputWrapperClass")}> <div className={getClassName("kcInputWrapperClass")}>
<input <input
type="text" type="text"
id="email" id="username"
className={getClassName("kcInputClass")} className={getClassName("kcInputClass")}
name="email" name="username"
defaultValue={register.formData.email ?? ""} defaultValue={register.formData.username ?? ""}
autoComplete="email" autoComplete="username"
/> />
</div> </div>
</div> </div>
{!realm.registrationEmailAsUsername && ( )}
{passwordRequired && (
<>
<div <div
className={clsx( className={clsx(
getClassName("kcFormGroupClass"), getClassName("kcFormGroupClass"),
messagesPerField.printIfExists("username", getClassName("kcFormGroupErrorClass")) messagesPerField.printIfExists("password", getClassName("kcFormGroupErrorClass"))
)} )}
> >
<div className={getClassName("kcLabelWrapperClass")}> <div className={getClassName("kcLabelWrapperClass")}>
<label htmlFor="username" className={getClassName("kcLabelClass")}> <label htmlFor="password" className={getClassName("kcLabelClass")}>
{msg("username")} {msg("password")}
</label> </label>
</div> </div>
<div className={getClassName("kcInputWrapperClass")}> <div className={getClassName("kcInputWrapperClass")}>
<input <input
type="text" type="password"
id="username" id="password"
className={getClassName("kcInputClass")} className={getClassName("kcInputClass")}
name="username" name="password"
defaultValue={register.formData.username ?? ""} autoComplete="new-password"
autoComplete="username"
/> />
</div> </div>
</div> </div>
)}
{passwordRequired && (
<>
<div
className={clsx(
getClassName("kcFormGroupClass"),
messagesPerField.printIfExists("password", getClassName("kcFormGroupErrorClass"))
)}
>
<div className={getClassName("kcLabelWrapperClass")}>
<label htmlFor="password" className={getClassName("kcLabelClass")}>
{msg("password")}
</label>
</div>
<div className={getClassName("kcInputWrapperClass")}>
<input
type="password"
id="password"
className={getClassName("kcInputClass")}
name="password"
autoComplete="new-password"
/>
</div>
</div>
<div <div
className={clsx( className={clsx(
getClassName("kcFormGroupClass"), getClassName("kcFormGroupClass"),
messagesPerField.printIfExists("password-confirm", getClassName("kcFormGroupErrorClass")) messagesPerField.printIfExists("password-confirm", getClassName("kcFormGroupErrorClass"))
)} )}
> >
<div className={getClassName("kcLabelWrapperClass")}> <div className={getClassName("kcLabelWrapperClass")}>
<label htmlFor="password-confirm" className={getClassName("kcLabelClass")}> <label htmlFor="password-confirm" className={getClassName("kcLabelClass")}>
{msg("passwordConfirm")} {msg("passwordConfirm")}
</label> </label>
</div>
<div className={getClassName("kcInputWrapperClass")}>
<input type="password" id="password-confirm" className={getClassName("kcInputClass")} name="password-confirm" />
</div>
</div> </div>
</>
)}
{recaptchaRequired && (
<div className="form-group">
<div className={getClassName("kcInputWrapperClass")}> <div className={getClassName("kcInputWrapperClass")}>
<div className="g-recaptcha" data-size="compact" data-sitekey={recaptchaSiteKey}></div> <input type="password" id="password-confirm" className={getClassName("kcInputClass")} name="password-confirm" />
</div> </div>
</div> </div>
)} </>
<div className={getClassName("kcFormGroupClass")}> )}
<div id="kc-form-options" className={getClassName("kcFormOptionsClass")}> {recaptchaRequired && (
<div className={getClassName("kcFormOptionsWrapperClass")}> <div className="form-group">
<span> <div className={getClassName("kcInputWrapperClass")}>
<a href={url.loginUrl}>{msg("backToLogin")}</a> <div className="g-recaptcha" data-size="compact" data-sitekey={recaptchaSiteKey}></div>
</span>
</div>
</div>
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
type="submit"
value={msgStr("doRegister")}
/>
</div> </div>
</div> </div>
</form> )}
} <div className={getClassName("kcFormGroupClass")}>
/> <div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")}>
<span>
<a href={url.loginUrl}>{msg("backToLogin")}</a>
</span>
</div>
</div>
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
type="submit"
value={msgStr("doRegister")}
/>
</div>
</div>
</form>
</Template>
); );
} }

View File

@ -26,46 +26,45 @@ export default function RegisterUserProfile(props: PageProps<Extract<KcContext,
displayMessage={messagesPerField.exists("global")} displayMessage={messagesPerField.exists("global")}
displayRequiredFields={true} displayRequiredFields={true}
headerNode={msg("registerTitle")} headerNode={msg("registerTitle")}
formNode={ >
<form id="kc-register-form" className={getClassName("kcFormClass")} action={url.registrationAction} method="post"> <form id="kc-register-form" className={getClassName("kcFormClass")} action={url.registrationAction} method="post">
<UserProfileFormFields <UserProfileFormFields
kcContext={kcContext} kcContext={kcContext}
onIsFormSubmittableValueChange={setIsFomSubmittable} onIsFormSubmittableValueChange={setIsFomSubmittable}
i18n={i18n} i18n={i18n}
getClassName={getClassName} getClassName={getClassName}
/> />
{recaptchaRequired && ( {recaptchaRequired && (
<div className="form-group"> <div className="form-group">
<div className={getClassName("kcInputWrapperClass")}> <div className={getClassName("kcInputWrapperClass")}>
<div className="g-recaptcha" data-size="compact" data-sitekey={recaptchaSiteKey} /> <div className="g-recaptcha" data-size="compact" data-sitekey={recaptchaSiteKey} />
</div>
</div>
)}
<div className={getClassName("kcFormGroupClass")} style={{ "marginBottom": 30 }}>
<div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")}>
<span>
<a href={url.loginUrl}>{msg("backToLogin")}</a>
</span>
</div>
</div>
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
type="submit"
value={msgStr("doRegister")}
disabled={!isFomSubmittable}
/>
</div> </div>
</div> </div>
</form> )}
} <div className={getClassName("kcFormGroupClass")} style={{ "marginBottom": 30 }}>
/> <div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")}>
<span>
<a href={url.loginUrl}>{msg("backToLogin")}</a>
</span>
</div>
</div>
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
type="submit"
value={msgStr("doRegister")}
disabled={!isFomSubmittable}
/>
</div>
</div>
</form>
</Template>
); );
} }

View File

@ -26,38 +26,31 @@ export default function Terms(props: PageProps<Extract<KcContext, { pageId: "ter
} }
return ( return (
<Template <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} displayMessage={false} headerNode={msg("termsTitle")}>
{...{ kcContext, i18n, doUseDefaultCss, classes }} <div id="kc-terms-text">{evtTermMarkdown.state && <Markdown>{evtTermMarkdown.state}</Markdown>}</div>
displayMessage={false} <form className="form-actions" action={url.loginAction} method="POST">
headerNode={msg("termsTitle")} <input
formNode={ className={clsx(
<> getClassName("kcButtonClass"),
<div id="kc-terms-text">{evtTermMarkdown.state && <Markdown>{evtTermMarkdown.state}</Markdown>}</div> getClassName("kcButtonClass"),
<form className="form-actions" action={url.loginAction} method="POST"> getClassName("kcButtonClass"),
<input getClassName("kcButtonPrimaryClass"),
className={clsx( getClassName("kcButtonLargeClass")
getClassName("kcButtonClass"), )}
getClassName("kcButtonClass"), name="accept"
getClassName("kcButtonClass"), id="kc-accept"
getClassName("kcButtonPrimaryClass"), type="submit"
getClassName("kcButtonLargeClass") value={msgStr("doAccept")}
)} />
name="accept" <input
id="kc-accept" className={clsx(getClassName("kcButtonClass"), getClassName("kcButtonDefaultClass"), getClassName("kcButtonLargeClass"))}
type="submit" name="cancel"
value={msgStr("doAccept")} id="kc-decline"
/> type="submit"
<input value={msgStr("doDecline")}
className={clsx(getClassName("kcButtonClass"), getClassName("kcButtonDefaultClass"), getClassName("kcButtonLargeClass"))} />
name="cancel" </form>
id="kc-decline" <div className="clearfix" />
type="submit" </Template>
value={msgStr("doDecline")}
/>
</form>
<div className="clearfix" />
</>
}
/>
); );
} }

View File

@ -21,66 +21,62 @@ export default function UpdateUserProfile(props: PageProps<Extract<KcContext, {
const [isFomSubmittable, setIsFomSubmittable] = useState(false); const [isFomSubmittable, setIsFomSubmittable] = useState(false);
return ( return (
<Template <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} headerNode={msg("loginProfileTitle")}>
{...{ kcContext, i18n, doUseDefaultCss, classes }} <form id="kc-update-profile-form" className={getClassName("kcFormClass")} action={url.loginAction} method="post">
headerNode={msg("loginProfileTitle")} <UserProfileFormFields
formNode={ kcContext={kcContext}
<form id="kc-update-profile-form" className={getClassName("kcFormClass")} action={url.loginAction} method="post"> onIsFormSubmittableValueChange={setIsFomSubmittable}
<UserProfileFormFields i18n={i18n}
kcContext={kcContext} getClassName={getClassName}
onIsFormSubmittableValueChange={setIsFomSubmittable} />
i18n={i18n}
getClassName={getClassName}
/>
<div className={getClassName("kcFormGroupClass")}> <div className={getClassName("kcFormGroupClass")}>
<div id="kc-form-options" className={getClassName("kcFormOptionsClass")}> <div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")}></div> <div className={getClassName("kcFormOptionsWrapperClass")}></div>
</div> </div>
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}> <div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
{isAppInitiatedAction ? ( {isAppInitiatedAction ? (
<> <>
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonLargeClass")
)}
type="submit"
value={msgStr("doSubmit")}
/>
<button
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonDefaultClass"),
getClassName("kcButtonLargeClass")
)}
type="submit"
name="cancel-aia"
value="true"
formNoValidate
>
{msg("doCancel")}
</button>
</>
) : (
<input <input
className={clsx( className={clsx(
getClassName("kcButtonClass"), getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"), getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass") getClassName("kcButtonLargeClass")
)} )}
type="submit" type="submit"
defaultValue={msgStr("doSubmit")} value={msgStr("doSubmit")}
disabled={!isFomSubmittable}
/> />
)} <button
</div> className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonDefaultClass"),
getClassName("kcButtonLargeClass")
)}
type="submit"
name="cancel-aia"
value="true"
formNoValidate
>
{msg("doCancel")}
</button>
</>
) : (
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
type="submit"
defaultValue={msgStr("doSubmit")}
disabled={!isFomSubmittable}
/>
)}
</div> </div>
</form> </div>
} </form>
/> </Template>
); );
} }

View File

@ -94,111 +94,102 @@ export default function WebauthnAuthenticate(props: PageProps<Extract<KcContext,
const [error, setError] = useState(""); const [error, setError] = useState("");
return ( return (
<Template <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} headerNode={msg("webauthn-login-title")}>
{...{ kcContext, i18n, doUseDefaultCss, classes }} <div id="kc-form-webauthn" className={getClassName("kcFormClass")}>
headerNode={msg("webauthn-login-title")} <form id="webauth" action={url.loginAction} ref={webAuthForm} method="post">
formNode={ <input type="hidden" id="clientDataJSON" name="clientDataJSON" value={clientDataJSON} />
<div id="kc-form-webauthn" className={getClassName("kcFormClass")}> <input type="hidden" id="authenticatorData" name="authenticatorData" value={authenticatorData} />
<form id="webauth" action={url.loginAction} ref={webAuthForm} method="post"> <input type="hidden" id="signature" name="signature" value={signature} />
<input type="hidden" id="clientDataJSON" name="clientDataJSON" value={clientDataJSON} /> <input type="hidden" id="credentialId" name="credentialId" value={credentialId} />
<input type="hidden" id="authenticatorData" name="authenticatorData" value={authenticatorData} /> <input type="hidden" id="userHandle" name="userHandle" value={userHandle} />
<input type="hidden" id="signature" name="signature" value={signature} /> <input type="hidden" id="error" name="error" value={error} />
<input type="hidden" id="credentialId" name="credentialId" value={credentialId} /> </form>
<input type="hidden" id="userHandle" name="userHandle" value={userHandle} /> <div className={getClassName("kcFormGroupClass")}>
<input type="hidden" id="error" name="error" value={error} /> {authenticators &&
</form> (() => (
<div className={getClassName("kcFormGroupClass")}> <form id="authn_select" className={getClassName("kcFormClass")}>
{authenticators && {authenticators.authenticators.map(authenticator => (
(() => ( <input type="hidden" name="authn_use_chk" value={authenticator.credentialId} key={authenticator.credentialId} />
<form id="authn_select" className={getClassName("kcFormClass")}> ))}
{authenticators.authenticators.map(authenticator => ( </form>
<input ))()}
type="hidden" {authenticators &&
name="authn_use_chk" shouldDisplayAuthenticators &&
value={authenticator.credentialId} (() => (
key={authenticator.credentialId} <>
/> {authenticators.authenticators.length > 1 && (
))} <p className={getClassName("kcSelectAuthListItemTitle")}>{msg("webauthn-available-authenticators")}</p>
</form>
))()}
{authenticators &&
shouldDisplayAuthenticators &&
(() => (
<>
{authenticators.authenticators.length > 1 && (
<p className={getClassName("kcSelectAuthListItemTitle")}>{msg("webauthn-available-authenticators")}</p>
)}
<div className={getClassName("kcFormClass")}>
{authenticators.authenticators.map(authenticator => (
<div id="kc-webauthn-authenticator" className={getClassName("kcSelectAuthListItemClass")}>
<div className={getClassName("kcSelectAuthListItemIconClass")}>
<i
className={clsx(
(() => {
const className = getClassName(authenticator.transports.iconClass as any);
return className.includes(" ")
? className
: [className, getClassName("kcWebAuthnDefaultIcon")];
})(),
getClassName("kcSelectAuthListItemIconPropertyClass")
)}
/>
</div>
<div className={getClassName("kcSelectAuthListItemBodyClass")}>
<div
id="kc-webauthn-authenticator-label"
className={getClassName("kcSelectAuthListItemHeadingClass")}
>
{authenticator.label}
</div>
{authenticator.transports && authenticator.transports.displayNameProperties.length && (
<div
id="kc-webauthn-authenticator-transport"
className={getClassName("kcSelectAuthListItemDescriptionClass")}
>
{authenticator.transports.displayNameProperties.map(
(transport: MessageKey, index: number) => (
<>
<span>{msg(transport)}</span>
{index < authenticator.transports.displayNameProperties.length - 1 && (
<span>{", "}</span>
)}
</>
)
)}
</div>
)}
<div className={getClassName("kcSelectAuthListItemDescriptionClass")}>
<span id="kc-webauthn-authenticator-created-label">{msg("webauthn-createdAt-label")}</span>
<span id="kc-webauthn-authenticator-created">{authenticator.createdAt}</span>
</div>
</div>
<div className={getClassName("kcSelectAuthListItemFillClass")} />
</div>
))}
</div>
</>
))()}
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
<input
id="authenticateWebAuthnButton"
type="button"
onClick={webAuthnAuthenticate}
autoFocus={true}
value={msgStr("webauthn-doAuthenticate")}
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)} )}
/> <div className={getClassName("kcFormClass")}>
</div> {authenticators.authenticators.map(authenticator => (
<div id="kc-webauthn-authenticator" className={getClassName("kcSelectAuthListItemClass")}>
<div className={getClassName("kcSelectAuthListItemIconClass")}>
<i
className={clsx(
(() => {
const className = getClassName(authenticator.transports.iconClass as any);
return className.includes(" ")
? className
: [className, getClassName("kcWebAuthnDefaultIcon")];
})(),
getClassName("kcSelectAuthListItemIconPropertyClass")
)}
/>
</div>
<div className={getClassName("kcSelectAuthListItemBodyClass")}>
<div
id="kc-webauthn-authenticator-label"
className={getClassName("kcSelectAuthListItemHeadingClass")}
>
{authenticator.label}
</div>
{authenticator.transports && authenticator.transports.displayNameProperties.length && (
<div
id="kc-webauthn-authenticator-transport"
className={getClassName("kcSelectAuthListItemDescriptionClass")}
>
{authenticator.transports.displayNameProperties.map(
(transport: MessageKey, index: number) => (
<>
<span>{msg(transport)}</span>
{index < authenticator.transports.displayNameProperties.length - 1 && (
<span>{", "}</span>
)}
</>
)
)}
</div>
)}
<div className={getClassName("kcSelectAuthListItemDescriptionClass")}>
<span id="kc-webauthn-authenticator-created-label">{msg("webauthn-createdAt-label")}</span>
<span id="kc-webauthn-authenticator-created">{authenticator.createdAt}</span>
</div>
</div>
<div className={getClassName("kcSelectAuthListItemFillClass")} />
</div>
))}
</div>
</>
))()}
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
<input
id="authenticateWebAuthnButton"
type="button"
onClick={webAuthnAuthenticate}
autoFocus={true}
value={msgStr("webauthn-doAuthenticate")}
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
/>
</div> </div>
</div> </div>
} </div>
/> </Template>
); );
} }