Better prettier params (changelog ignore)
This commit is contained in:
@ -4,31 +4,29 @@ import type { KcProps } from "./KcProps";
|
||||
import type { KcContextBase } from "../getKcContext/KcContextBase";
|
||||
import { useKcMessage } from "../i18n/useKcMessage";
|
||||
|
||||
export const Error = memo(
|
||||
({ kcContext, ...props }: { kcContext: KcContextBase.Error } & KcProps) => {
|
||||
const { msg } = useKcMessage();
|
||||
export const Error = memo(({ kcContext, ...props }: { kcContext: KcContextBase.Error } & KcProps) => {
|
||||
const { msg } = useKcMessage();
|
||||
|
||||
const { message, client } = kcContext;
|
||||
const { message, client } = kcContext;
|
||||
|
||||
return (
|
||||
<Template
|
||||
{...{ kcContext, ...props }}
|
||||
doFetchDefaultThemeResources={true}
|
||||
displayMessage={false}
|
||||
headerNode={msg("errorTitle")}
|
||||
formNode={
|
||||
<div id="kc-error-message">
|
||||
<p className="instruction">{message.summary}</p>
|
||||
{client !== undefined && client.baseUrl !== undefined && (
|
||||
<p>
|
||||
<a id="backToApplication" href={client.baseUrl}>
|
||||
{msg("backToApplication")}
|
||||
</a>
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
);
|
||||
},
|
||||
);
|
||||
return (
|
||||
<Template
|
||||
{...{ kcContext, ...props }}
|
||||
doFetchDefaultThemeResources={true}
|
||||
displayMessage={false}
|
||||
headerNode={msg("errorTitle")}
|
||||
formNode={
|
||||
<div id="kc-error-message">
|
||||
<p className="instruction">{message.summary}</p>
|
||||
{client !== undefined && client.baseUrl !== undefined && (
|
||||
<p>
|
||||
<a id="backToApplication" href={client.baseUrl}>
|
||||
{msg("backToApplication")}
|
||||
</a>
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
@ -5,75 +5,45 @@ import { assert } from "../tools/assert";
|
||||
import type { KcContextBase } from "../getKcContext/KcContextBase";
|
||||
import { useKcMessage } from "../i18n/useKcMessage";
|
||||
|
||||
export const Info = memo(
|
||||
({ kcContext, ...props }: { kcContext: KcContextBase.Info } & KcProps) => {
|
||||
const { msg } = useKcMessage();
|
||||
export const Info = memo(({ kcContext, ...props }: { kcContext: KcContextBase.Info } & KcProps) => {
|
||||
const { msg } = useKcMessage();
|
||||
|
||||
assert(kcContext.message !== undefined);
|
||||
assert(kcContext.message !== undefined);
|
||||
|
||||
const {
|
||||
messageHeader,
|
||||
message,
|
||||
requiredActions,
|
||||
skipLink,
|
||||
pageRedirectUri,
|
||||
actionUri,
|
||||
client,
|
||||
} = kcContext;
|
||||
const { messageHeader, message, requiredActions, skipLink, pageRedirectUri, actionUri, client } = kcContext;
|
||||
|
||||
return (
|
||||
<Template
|
||||
{...{ kcContext, ...props }}
|
||||
doFetchDefaultThemeResources={true}
|
||||
displayMessage={false}
|
||||
headerNode={
|
||||
messageHeader !== undefined ? (
|
||||
<>{messageHeader}</>
|
||||
) : (
|
||||
<>{message.summary}</>
|
||||
)
|
||||
}
|
||||
formNode={
|
||||
<div id="kc-info-message">
|
||||
<p className="instruction">
|
||||
{message.summary}
|
||||
return (
|
||||
<Template
|
||||
{...{ kcContext, ...props }}
|
||||
doFetchDefaultThemeResources={true}
|
||||
displayMessage={false}
|
||||
headerNode={messageHeader !== undefined ? <>{messageHeader}</> : <>{message.summary}</>}
|
||||
formNode={
|
||||
<div id="kc-info-message">
|
||||
<p className="instruction">
|
||||
{message.summary}
|
||||
|
||||
{requiredActions !== undefined && (
|
||||
<b>
|
||||
{requiredActions
|
||||
.map(requiredAction =>
|
||||
msg(
|
||||
`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>
|
||||
)
|
||||
{requiredActions !== undefined && (
|
||||
<b>{requiredActions.map(requiredAction => msg(`requiredAction.${requiredAction}` as const)).join(",")}</b>
|
||||
)}
|
||||
</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>
|
||||
}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
@ -13,31 +13,29 @@ import { LoginOtp } from "./LoginOtp";
|
||||
import { LoginUpdateProfile } from "./LoginUpdateProfile";
|
||||
import { LoginIdpLinkConfirm } from "./LoginIdpLinkConfirm";
|
||||
|
||||
export const KcApp = memo(
|
||||
({ kcContext, ...props }: { kcContext: KcContextBase } & KcProps) => {
|
||||
switch (kcContext.pageId) {
|
||||
case "login.ftl":
|
||||
return <Login {...{ kcContext, ...props }} />;
|
||||
case "register.ftl":
|
||||
return <Register {...{ kcContext, ...props }} />;
|
||||
case "register-user-profile.ftl":
|
||||
return <RegisterUserProfile {...{ kcContext, ...props }} />;
|
||||
case "info.ftl":
|
||||
return <Info {...{ kcContext, ...props }} />;
|
||||
case "error.ftl":
|
||||
return <Error {...{ kcContext, ...props }} />;
|
||||
case "login-reset-password.ftl":
|
||||
return <LoginResetPassword {...{ kcContext, ...props }} />;
|
||||
case "login-verify-email.ftl":
|
||||
return <LoginVerifyEmail {...{ kcContext, ...props }} />;
|
||||
case "terms.ftl":
|
||||
return <Terms {...{ kcContext, ...props }} />;
|
||||
case "login-otp.ftl":
|
||||
return <LoginOtp {...{ kcContext, ...props }} />;
|
||||
case "login-update-profile.ftl":
|
||||
return <LoginUpdateProfile {...{ kcContext, ...props }} />;
|
||||
case "login-idp-link-confirm.ftl":
|
||||
return <LoginIdpLinkConfirm {...{ kcContext, ...props }} />;
|
||||
}
|
||||
},
|
||||
);
|
||||
export const KcApp = memo(({ kcContext, ...props }: { kcContext: KcContextBase } & KcProps) => {
|
||||
switch (kcContext.pageId) {
|
||||
case "login.ftl":
|
||||
return <Login {...{ kcContext, ...props }} />;
|
||||
case "register.ftl":
|
||||
return <Register {...{ kcContext, ...props }} />;
|
||||
case "register-user-profile.ftl":
|
||||
return <RegisterUserProfile {...{ kcContext, ...props }} />;
|
||||
case "info.ftl":
|
||||
return <Info {...{ kcContext, ...props }} />;
|
||||
case "error.ftl":
|
||||
return <Error {...{ kcContext, ...props }} />;
|
||||
case "login-reset-password.ftl":
|
||||
return <LoginResetPassword {...{ kcContext, ...props }} />;
|
||||
case "login-verify-email.ftl":
|
||||
return <LoginVerifyEmail {...{ kcContext, ...props }} />;
|
||||
case "terms.ftl":
|
||||
return <Terms {...{ kcContext, ...props }} />;
|
||||
case "login-otp.ftl":
|
||||
return <LoginOtp {...{ kcContext, ...props }} />;
|
||||
case "login-update-profile.ftl":
|
||||
return <LoginUpdateProfile {...{ kcContext, ...props }} />;
|
||||
case "login-idp-link-confirm.ftl":
|
||||
return <LoginIdpLinkConfirm {...{ kcContext, ...props }} />;
|
||||
}
|
||||
});
|
||||
|
@ -70,9 +70,7 @@ export const defaultKcTemplateProps = {
|
||||
assert<typeof defaultKcTemplateProps extends KcTemplateProps ? true : false>();
|
||||
|
||||
/** Tu use if you don't want any default */
|
||||
export const allClearKcTemplateProps = allPropertiesValuesToUndefined(
|
||||
defaultKcTemplateProps,
|
||||
);
|
||||
export const allClearKcTemplateProps = allPropertiesValuesToUndefined(defaultKcTemplateProps);
|
||||
|
||||
assert<typeof allClearKcTemplateProps extends KcTemplateProps ? true : false>();
|
||||
|
||||
@ -134,31 +132,13 @@ export const defaultKcProps = {
|
||||
"kcLogoLink": "http://www.keycloak.org",
|
||||
"kcLogoClass": "login-pf-brand",
|
||||
"kcContainerClass": "container-fluid",
|
||||
"kcContentClass": [
|
||||
"col-sm-8",
|
||||
"col-sm-offset-2",
|
||||
"col-md-6",
|
||||
"col-md-offset-3",
|
||||
"col-lg-6",
|
||||
"col-lg-offset-3",
|
||||
],
|
||||
"kcContentClass": ["col-sm-8", "col-sm-offset-2", "col-md-6", "col-md-offset-3", "col-lg-6", "col-lg-offset-3"],
|
||||
"kcFeedbackAreaClass": ["col-md-12"],
|
||||
"kcLocaleClass": ["col-xs-12", "col-sm-1"],
|
||||
"kcAlertIconClasserror": ["pficon", "pficon-error-circle-o"],
|
||||
|
||||
"kcFormAreaClass": [
|
||||
"col-sm-10",
|
||||
"col-sm-offset-1",
|
||||
"col-md-8",
|
||||
"col-md-offset-2",
|
||||
"col-lg-8",
|
||||
"col-lg-offset-2",
|
||||
],
|
||||
"kcFormSocialAccountListClass": [
|
||||
"login-pf-social",
|
||||
"list-unstyled",
|
||||
"login-pf-social-all",
|
||||
],
|
||||
"kcFormAreaClass": ["col-sm-10", "col-sm-offset-1", "col-md-8", "col-md-offset-2", "col-lg-8", "col-lg-offset-2"],
|
||||
"kcFormSocialAccountListClass": ["login-pf-social", "list-unstyled", "login-pf-social-all"],
|
||||
"kcFormSocialAccountDoubleListClass": ["login-pf-social-double-col"],
|
||||
"kcFormSocialAccountListLinkClass": ["login-pf-social-link"],
|
||||
"kcWebAuthnKeyIcon": ["pficon", "pficon-key"],
|
||||
@ -167,25 +147,14 @@ export const defaultKcProps = {
|
||||
"kcFormGroupErrorClass": ["has-error"],
|
||||
"kcLabelClass": ["control-label"],
|
||||
"kcInputClass": ["form-control"],
|
||||
"kcInputErrorMessageClass": [
|
||||
"pf-c-form__helper-text",
|
||||
"pf-m-error",
|
||||
"required",
|
||||
"kc-feedback-text",
|
||||
],
|
||||
"kcInputErrorMessageClass": ["pf-c-form__helper-text", "pf-m-error", "required", "kc-feedback-text"],
|
||||
"kcInputWrapperClass": ["col-xs-12", "col-sm-12", "col-md-12", "col-lg-12"],
|
||||
"kcFormOptionsClass": ["col-xs-12", "col-sm-12", "col-md-12", "col-lg-12"],
|
||||
"kcFormButtonsClass": ["col-xs-12", "col-sm-12", "col-md-12", "col-lg-12"],
|
||||
"kcFormSettingClass": ["login-pf-settings"],
|
||||
"kcTextareaClass": ["form-control"],
|
||||
|
||||
"kcInfoAreaClass": [
|
||||
"col-xs-12",
|
||||
"col-sm-4",
|
||||
"col-md-4",
|
||||
"col-lg-5",
|
||||
"details",
|
||||
],
|
||||
"kcInfoAreaClass": ["col-xs-12", "col-sm-4", "col-md-4", "col-lg-5", "details"],
|
||||
|
||||
// user-profile grouping
|
||||
"kcFormGroupHeader": ["pf-c-form__group"],
|
||||
@ -220,19 +189,10 @@ export const defaultKcProps = {
|
||||
"kcAuthenticatorPasswordClass": ["fa", "fa-unlock list-view-pf-icon-lg"],
|
||||
"kcAuthenticatorOTPClass": ["fa", "fa-mobile", "list-view-pf-icon-lg"],
|
||||
"kcAuthenticatorWebAuthnClass": ["fa", "fa-key", "list-view-pf-icon-lg"],
|
||||
"kcAuthenticatorWebAuthnPasswordlessClass": [
|
||||
"fa",
|
||||
"fa-key",
|
||||
"list-view-pf-icon-lg",
|
||||
],
|
||||
"kcAuthenticatorWebAuthnPasswordlessClass": ["fa", "fa-key", "list-view-pf-icon-lg"],
|
||||
|
||||
//css classes for the OTP Login Form
|
||||
"kcSelectOTPListClass": [
|
||||
"card-pf",
|
||||
"card-pf-view",
|
||||
"card-pf-view-select",
|
||||
"card-pf-view-single-select",
|
||||
],
|
||||
"kcSelectOTPListClass": ["card-pf", "card-pf-view", "card-pf-view-select", "card-pf-view-single-select"],
|
||||
"kcSelectOTPListItemClass": ["card-pf-body", "card-pf-top-element"],
|
||||
"kcAuthenticatorOtpCircleClass": ["fa", "fa-mobile", "card-pf-icon-circle"],
|
||||
"kcSelectOTPItemHeadingClass": ["card-pf-title", "text-center"],
|
||||
|
@ -6,241 +6,162 @@ import { useKcMessage } from "../i18n/useKcMessage";
|
||||
import { useCssAndCx } from "tss-react";
|
||||
import { useConstCallback } from "powerhooks/useConstCallback";
|
||||
|
||||
export const Login = memo(
|
||||
({ kcContext, ...props }: { kcContext: KcContextBase.Login } & KcProps) => {
|
||||
const {
|
||||
social,
|
||||
realm,
|
||||
url,
|
||||
usernameEditDisabled,
|
||||
login,
|
||||
auth,
|
||||
registrationDisabled,
|
||||
} = kcContext;
|
||||
export const Login = memo(({ kcContext, ...props }: { kcContext: KcContextBase.Login } & KcProps) => {
|
||||
const { social, realm, url, usernameEditDisabled, login, auth, registrationDisabled } = kcContext;
|
||||
|
||||
const { msg, msgStr } = useKcMessage();
|
||||
const { msg, msgStr } = useKcMessage();
|
||||
|
||||
const { cx } = useCssAndCx();
|
||||
const { cx } = useCssAndCx();
|
||||
|
||||
const [isLoginButtonDisabled, setIsLoginButtonDisabled] =
|
||||
useState(false);
|
||||
const [isLoginButtonDisabled, setIsLoginButtonDisabled] = useState(false);
|
||||
|
||||
const onSubmit = useConstCallback(
|
||||
() => (setIsLoginButtonDisabled(true), true),
|
||||
);
|
||||
const onSubmit = useConstCallback(() => (setIsLoginButtonDisabled(true), true));
|
||||
|
||||
return (
|
||||
<Template
|
||||
{...{ kcContext, ...props }}
|
||||
doFetchDefaultThemeResources={true}
|
||||
displayInfo={social.displayInfo}
|
||||
displayWide={realm.password && social.providers !== undefined}
|
||||
headerNode={msg("doLogIn")}
|
||||
formNode={
|
||||
return (
|
||||
<Template
|
||||
{...{ kcContext, ...props }}
|
||||
doFetchDefaultThemeResources={true}
|
||||
displayInfo={social.displayInfo}
|
||||
displayWide={realm.password && social.providers !== undefined}
|
||||
headerNode={msg("doLogIn")}
|
||||
formNode={
|
||||
<div id="kc-form" className={cx(realm.password && social.providers !== undefined && props.kcContentWrapperClass)}>
|
||||
<div
|
||||
id="kc-form"
|
||||
className={cx(
|
||||
realm.password &&
|
||||
social.providers !== undefined &&
|
||||
props.kcContentWrapperClass,
|
||||
)}
|
||||
id="kc-form-wrapper"
|
||||
className={cx(realm.password && social.providers && [props.kcFormSocialAccountContentClass, props.kcFormSocialAccountClass])}
|
||||
>
|
||||
<div
|
||||
id="kc-form-wrapper"
|
||||
className={cx(
|
||||
realm.password &&
|
||||
social.providers && [
|
||||
props.kcFormSocialAccountContentClass,
|
||||
props.kcFormSocialAccountClass,
|
||||
],
|
||||
)}
|
||||
>
|
||||
{realm.password && (
|
||||
<form
|
||||
id="kc-form-login"
|
||||
onSubmit={onSubmit}
|
||||
action={url.loginAction}
|
||||
method="post"
|
||||
>
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<label
|
||||
htmlFor="username"
|
||||
className={cx(props.kcLabelClass)}
|
||||
>
|
||||
{!realm.loginWithEmailAllowed
|
||||
? msg("username")
|
||||
: !realm.registrationEmailAsUsername
|
||||
? msg("usernameOrEmail")
|
||||
: msg("email")}
|
||||
</label>
|
||||
<input
|
||||
tabIndex={1}
|
||||
id="username"
|
||||
className={cx(props.kcInputClass)}
|
||||
name="username"
|
||||
defaultValue={login.username ?? ""}
|
||||
type="text"
|
||||
{...(usernameEditDisabled
|
||||
? { "disabled": true }
|
||||
: {
|
||||
"autoFocus": true,
|
||||
"autoComplete": "off",
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<label
|
||||
htmlFor="password"
|
||||
className={cx(props.kcLabelClass)}
|
||||
>
|
||||
{msg("password")}
|
||||
</label>
|
||||
<input
|
||||
tabIndex={2}
|
||||
id="password"
|
||||
className={cx(props.kcInputClass)}
|
||||
name="password"
|
||||
type="password"
|
||||
autoComplete="off"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={cx(
|
||||
props.kcFormGroupClass,
|
||||
props.kcFormSettingClass,
|
||||
{realm.password && (
|
||||
<form id="kc-form-login" onSubmit={onSubmit} action={url.loginAction} method="post">
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<label htmlFor="username" className={cx(props.kcLabelClass)}>
|
||||
{!realm.loginWithEmailAllowed
|
||||
? msg("username")
|
||||
: !realm.registrationEmailAsUsername
|
||||
? msg("usernameOrEmail")
|
||||
: msg("email")}
|
||||
</label>
|
||||
<input
|
||||
tabIndex={1}
|
||||
id="username"
|
||||
className={cx(props.kcInputClass)}
|
||||
name="username"
|
||||
defaultValue={login.username ?? ""}
|
||||
type="text"
|
||||
{...(usernameEditDisabled
|
||||
? { "disabled": true }
|
||||
: {
|
||||
"autoFocus": true,
|
||||
"autoComplete": "off",
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<label htmlFor="password" className={cx(props.kcLabelClass)}>
|
||||
{msg("password")}
|
||||
</label>
|
||||
<input
|
||||
tabIndex={2}
|
||||
id="password"
|
||||
className={cx(props.kcInputClass)}
|
||||
name="password"
|
||||
type="password"
|
||||
autoComplete="off"
|
||||
/>
|
||||
</div>
|
||||
<div className={cx(props.kcFormGroupClass, props.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 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={cx(
|
||||
props.kcFormOptionsWrapperClass,
|
||||
)}
|
||||
>
|
||||
{realm.resetPasswordAllowed && (
|
||||
<span>
|
||||
<a
|
||||
tabIndex={5}
|
||||
href={
|
||||
url.loginResetCredentialsUrl
|
||||
}
|
||||
>
|
||||
{msg(
|
||||
"doForgotPassword",
|
||||
)}
|
||||
</a>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
id="kc-form-buttons"
|
||||
className={cx(props.kcFormGroupClass)}
|
||||
>
|
||||
<input
|
||||
type="hidden"
|
||||
id="id-hidden-input"
|
||||
name="credentialId"
|
||||
{...(auth?.selectedCredential !==
|
||||
undefined
|
||||
? {
|
||||
"value":
|
||||
auth.selectedCredential,
|
||||
}
|
||||
: {})}
|
||||
/>
|
||||
<input
|
||||
tabIndex={4}
|
||||
className={cx(
|
||||
props.kcButtonClass,
|
||||
props.kcButtonPrimaryClass,
|
||||
props.kcButtonBlockClass,
|
||||
props.kcButtonLargeClass,
|
||||
)}
|
||||
name="login"
|
||||
id="kc-login"
|
||||
type="submit"
|
||||
value={msgStr("doLogIn")}
|
||||
disabled={isLoginButtonDisabled}
|
||||
/>
|
||||
<div className={cx(props.kcFormOptionsWrapperClass)}>
|
||||
{realm.resetPasswordAllowed && (
|
||||
<span>
|
||||
<a tabIndex={5} href={url.loginResetCredentialsUrl}>
|
||||
{msg("doForgotPassword")}
|
||||
</a>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
{realm.password && social.providers !== undefined && (
|
||||
<div
|
||||
id="kc-social-providers"
|
||||
className={cx(
|
||||
props.kcFormSocialAccountContentClass,
|
||||
props.kcFormSocialAccountClass,
|
||||
)}
|
||||
>
|
||||
<ul
|
||||
className={cx(
|
||||
props.kcFormSocialAccountListClass,
|
||||
social.providers.length > 4 &&
|
||||
props.kcFormSocialAccountDoubleListClass,
|
||||
)}
|
||||
>
|
||||
{social.providers.map(p => (
|
||||
<li
|
||||
key={p.providerId}
|
||||
className={cx(
|
||||
props.kcFormSocialAccountListLinkClass,
|
||||
)}
|
||||
>
|
||||
<a
|
||||
href={p.loginUrl}
|
||||
id={`zocial-${p.alias}`}
|
||||
className={cx(
|
||||
"zocial",
|
||||
p.providerId,
|
||||
)}
|
||||
>
|
||||
<span>{p.displayName}</span>
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="kc-form-buttons" className={cx(props.kcFormGroupClass)}>
|
||||
<input
|
||||
type="hidden"
|
||||
id="id-hidden-input"
|
||||
name="credentialId"
|
||||
{...(auth?.selectedCredential !== undefined
|
||||
? {
|
||||
"value": auth.selectedCredential,
|
||||
}
|
||||
: {})}
|
||||
/>
|
||||
<input
|
||||
tabIndex={4}
|
||||
className={cx(
|
||||
props.kcButtonClass,
|
||||
props.kcButtonPrimaryClass,
|
||||
props.kcButtonBlockClass,
|
||||
props.kcButtonLargeClass,
|
||||
)}
|
||||
name="login"
|
||||
id="kc-login"
|
||||
type="submit"
|
||||
value={msgStr("doLogIn")}
|
||||
disabled={isLoginButtonDisabled}
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
infoNode={
|
||||
realm.password &&
|
||||
realm.registrationAllowed &&
|
||||
!registrationDisabled && (
|
||||
<div id="kc-registration">
|
||||
<span>
|
||||
{msg("noAccount")}
|
||||
<a tabIndex={6} href={url.registrationUrl}>
|
||||
{msg("doRegister")}
|
||||
</a>
|
||||
</span>
|
||||
{realm.password && social.providers !== undefined && (
|
||||
<div id="kc-social-providers" className={cx(props.kcFormSocialAccountContentClass, props.kcFormSocialAccountClass)}>
|
||||
<ul
|
||||
className={cx(
|
||||
props.kcFormSocialAccountListClass,
|
||||
social.providers.length > 4 && props.kcFormSocialAccountDoubleListClass,
|
||||
)}
|
||||
>
|
||||
{social.providers.map(p => (
|
||||
<li key={p.providerId} className={cx(props.kcFormSocialAccountListLinkClass)}>
|
||||
<a href={p.loginUrl} id={`zocial-${p.alias}`} className={cx("zocial", p.providerId)}>
|
||||
<span>{p.displayName}</span>
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
/>
|
||||
);
|
||||
},
|
||||
);
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
infoNode={
|
||||
realm.password &&
|
||||
realm.registrationAllowed &&
|
||||
!registrationDisabled && (
|
||||
<div id="kc-registration">
|
||||
<span>
|
||||
{msg("noAccount")}
|
||||
<a tabIndex={6} href={url.registrationUrl}>
|
||||
{msg("doRegister")}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
@ -5,61 +5,42 @@ import type { KcContextBase } from "../getKcContext/KcContextBase";
|
||||
import { useKcMessage } from "../i18n/useKcMessage";
|
||||
import { useCssAndCx } from "tss-react";
|
||||
|
||||
export const LoginIdpLinkConfirm = memo(
|
||||
({
|
||||
kcContext,
|
||||
...props
|
||||
}: { kcContext: KcContextBase.LoginIdpLinkConfirm } & KcProps) => {
|
||||
const { url, idpAlias } = kcContext;
|
||||
export const LoginIdpLinkConfirm = memo(({ kcContext, ...props }: { kcContext: KcContextBase.LoginIdpLinkConfirm } & KcProps) => {
|
||||
const { url, idpAlias } = kcContext;
|
||||
|
||||
const { msg } = useKcMessage();
|
||||
const { msg } = useKcMessage();
|
||||
|
||||
const { cx } = useCssAndCx();
|
||||
const { cx } = useCssAndCx();
|
||||
|
||||
return (
|
||||
<Template
|
||||
{...{ kcContext, ...props }}
|
||||
doFetchDefaultThemeResources={true}
|
||||
headerNode={msg("confirmLinkIdpTitle")}
|
||||
formNode={
|
||||
<form
|
||||
id="kc-register-form"
|
||||
action={url.loginAction}
|
||||
method="post"
|
||||
>
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<button
|
||||
type="submit"
|
||||
className={cx(
|
||||
props.kcButtonClass,
|
||||
props.kcButtonDefaultClass,
|
||||
props.kcButtonBlockClass,
|
||||
props.kcButtonLargeClass,
|
||||
)}
|
||||
name="submitAction"
|
||||
id="updateProfile"
|
||||
value="updateProfile"
|
||||
>
|
||||
{msg("confirmLinkIdpReviewProfile")}
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
className={cx(
|
||||
props.kcButtonClass,
|
||||
props.kcButtonDefaultClass,
|
||||
props.kcButtonBlockClass,
|
||||
props.kcButtonLargeClass,
|
||||
)}
|
||||
name="submitAction"
|
||||
id="linkAccount"
|
||||
value="linkAccount"
|
||||
>
|
||||
{msg("confirmLinkIdpContinue", idpAlias)}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
/>
|
||||
);
|
||||
},
|
||||
);
|
||||
return (
|
||||
<Template
|
||||
{...{ kcContext, ...props }}
|
||||
doFetchDefaultThemeResources={true}
|
||||
headerNode={msg("confirmLinkIdpTitle")}
|
||||
formNode={
|
||||
<form id="kc-register-form" action={url.loginAction} method="post">
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<button
|
||||
type="submit"
|
||||
className={cx(props.kcButtonClass, props.kcButtonDefaultClass, props.kcButtonBlockClass, props.kcButtonLargeClass)}
|
||||
name="submitAction"
|
||||
id="updateProfile"
|
||||
value="updateProfile"
|
||||
>
|
||||
{msg("confirmLinkIdpReviewProfile")}
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
className={cx(props.kcButtonClass, props.kcButtonDefaultClass, props.kcButtonBlockClass, props.kcButtonLargeClass)}
|
||||
name="submitAction"
|
||||
id="linkAccount"
|
||||
value="linkAccount"
|
||||
>
|
||||
{msg("confirmLinkIdpContinue", idpAlias)}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
@ -7,148 +7,84 @@ import { appendHead } from "../tools/appendHead";
|
||||
import { join as pathJoin } from "path";
|
||||
import { useCssAndCx } from "tss-react";
|
||||
|
||||
export const LoginOtp = memo(
|
||||
({
|
||||
kcContext,
|
||||
...props
|
||||
}: { kcContext: KcContextBase.LoginOtp } & KcProps) => {
|
||||
const { otpLogin, url } = kcContext;
|
||||
export const LoginOtp = memo(({ kcContext, ...props }: { kcContext: KcContextBase.LoginOtp } & KcProps) => {
|
||||
const { otpLogin, url } = kcContext;
|
||||
|
||||
const { cx } = useCssAndCx();
|
||||
const { cx } = useCssAndCx();
|
||||
|
||||
const { msg, msgStr } = useKcMessage();
|
||||
const { msg, msgStr } = useKcMessage();
|
||||
|
||||
useEffect(() => {
|
||||
let isCleanedUp = false;
|
||||
useEffect(() => {
|
||||
let isCleanedUp = false;
|
||||
|
||||
appendHead({
|
||||
"type": "javascript",
|
||||
"src": pathJoin(
|
||||
kcContext.url.resourcesCommonPath,
|
||||
"node_modules/jquery/dist/jquery.min.js",
|
||||
),
|
||||
}).then(() => {
|
||||
if (isCleanedUp) return;
|
||||
appendHead({
|
||||
"type": "javascript",
|
||||
"src": pathJoin(kcContext.url.resourcesCommonPath, "node_modules/jquery/dist/jquery.min.js"),
|
||||
}).then(() => {
|
||||
if (isCleanedUp) return;
|
||||
|
||||
evaluateInlineScript();
|
||||
});
|
||||
evaluateInlineScript();
|
||||
});
|
||||
|
||||
return () => {
|
||||
isCleanedUp = true;
|
||||
};
|
||||
}, []);
|
||||
return () => {
|
||||
isCleanedUp = true;
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Template
|
||||
{...{ kcContext, ...props }}
|
||||
doFetchDefaultThemeResources={true}
|
||||
headerNode={msg("doLogIn")}
|
||||
formNode={
|
||||
<form
|
||||
id="kc-otp-login-form"
|
||||
className={cx(props.kcFormClass)}
|
||||
action={url.loginAction}
|
||||
method="post"
|
||||
>
|
||||
{otpLogin.userOtpCredentials.length > 1 && (
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
{otpLogin.userOtpCredentials.map(
|
||||
otpCredential => (
|
||||
<div
|
||||
key={otpCredential.id}
|
||||
className={cx(
|
||||
props.kcSelectOTPListClass,
|
||||
)}
|
||||
>
|
||||
<input
|
||||
type="hidden"
|
||||
value="${otpCredential.id}"
|
||||
/>
|
||||
<div
|
||||
className={cx(
|
||||
props.kcSelectOTPListItemClass,
|
||||
)}
|
||||
>
|
||||
<span
|
||||
className={cx(
|
||||
props.kcAuthenticatorOtpCircleClass,
|
||||
)}
|
||||
/>
|
||||
<h2
|
||||
className={cx(
|
||||
props.kcSelectOTPItemHeadingClass,
|
||||
)}
|
||||
>
|
||||
{
|
||||
otpCredential.userLabel
|
||||
}
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
return (
|
||||
<Template
|
||||
{...{ kcContext, ...props }}
|
||||
doFetchDefaultThemeResources={true}
|
||||
headerNode={msg("doLogIn")}
|
||||
formNode={
|
||||
<form id="kc-otp-login-form" className={cx(props.kcFormClass)} action={url.loginAction} method="post">
|
||||
{otpLogin.userOtpCredentials.length > 1 && (
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<div className={cx(props.kcLabelWrapperClass)}>
|
||||
<label
|
||||
htmlFor="otp"
|
||||
className={cx(props.kcLabelClass)}
|
||||
>
|
||||
{msg("loginOtpOneTime")}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<input
|
||||
id="otp"
|
||||
name="otp"
|
||||
autoComplete="off"
|
||||
type="text"
|
||||
className={cx(props.kcInputClass)}
|
||||
autoFocus
|
||||
/>
|
||||
{otpLogin.userOtpCredentials.map(otpCredential => (
|
||||
<div key={otpCredential.id} className={cx(props.kcSelectOTPListClass)}>
|
||||
<input type="hidden" value="${otpCredential.id}" />
|
||||
<div className={cx(props.kcSelectOTPListItemClass)}>
|
||||
<span className={cx(props.kcAuthenticatorOtpCircleClass)} />
|
||||
<h2 className={cx(props.kcSelectOTPItemHeadingClass)}>{otpCredential.userLabel}</h2>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<div
|
||||
id="kc-form-options"
|
||||
className={cx(props.kcFormOptionsClass)}
|
||||
>
|
||||
<div
|
||||
className={cx(
|
||||
props.kcFormOptionsWrapperClass,
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="kc-form-buttons"
|
||||
className={cx(props.kcFormButtonsClass)}
|
||||
>
|
||||
<input
|
||||
className={cx(
|
||||
props.kcButtonClass,
|
||||
props.kcButtonPrimaryClass,
|
||||
props.kcButtonBlockClass,
|
||||
props.kcButtonLargeClass,
|
||||
)}
|
||||
name="login"
|
||||
id="kc-login"
|
||||
type="submit"
|
||||
value={msgStr("doLogIn")}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<div className={cx(props.kcLabelWrapperClass)}>
|
||||
<label htmlFor="otp" className={cx(props.kcLabelClass)}>
|
||||
{msg("loginOtpOneTime")}
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
/>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<input id="otp" name="otp" autoComplete="off" type="text" className={cx(props.kcInputClass)} autoFocus />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<div id="kc-form-options" className={cx(props.kcFormOptionsClass)}>
|
||||
<div className={cx(props.kcFormOptionsWrapperClass)} />
|
||||
</div>
|
||||
|
||||
<div id="kc-form-buttons" className={cx(props.kcFormButtonsClass)}>
|
||||
<input
|
||||
className={cx(props.kcButtonClass, props.kcButtonPrimaryClass, props.kcButtonBlockClass, props.kcButtonLargeClass)}
|
||||
name="login"
|
||||
id="kc-login"
|
||||
type="submit"
|
||||
value={msgStr("doLogIn")}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
declare const $: any;
|
||||
|
||||
|
@ -5,101 +5,62 @@ import type { KcContextBase } from "../getKcContext/KcContextBase";
|
||||
import { useKcMessage } from "../i18n/useKcMessage";
|
||||
import { useCssAndCx } from "tss-react";
|
||||
|
||||
export const LoginResetPassword = memo(
|
||||
({
|
||||
kcContext,
|
||||
...props
|
||||
}: { kcContext: KcContextBase.LoginResetPassword } & KcProps) => {
|
||||
const { url, realm, auth } = kcContext;
|
||||
export const LoginResetPassword = memo(({ kcContext, ...props }: { kcContext: KcContextBase.LoginResetPassword } & KcProps) => {
|
||||
const { url, realm, auth } = kcContext;
|
||||
|
||||
const { msg, msgStr } = useKcMessage();
|
||||
const { msg, msgStr } = useKcMessage();
|
||||
|
||||
const { cx } = useCssAndCx();
|
||||
const { cx } = useCssAndCx();
|
||||
|
||||
return (
|
||||
<Template
|
||||
{...{ kcContext, ...props }}
|
||||
doFetchDefaultThemeResources={true}
|
||||
displayMessage={false}
|
||||
headerNode={msg("emailForgotTitle")}
|
||||
formNode={
|
||||
<form
|
||||
id="kc-reset-password-form"
|
||||
className={cx(props.kcFormClass)}
|
||||
action={url.loginAction}
|
||||
method="post"
|
||||
>
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<div className={cx(props.kcLabelWrapperClass)}>
|
||||
<label
|
||||
htmlFor="username"
|
||||
className={cx(props.kcLabelClass)}
|
||||
>
|
||||
{!realm.loginWithEmailAllowed
|
||||
? msg("username")
|
||||
: !realm.registrationEmailAsUsername
|
||||
? msg("usernameOrEmail")
|
||||
: msg("email")}
|
||||
</label>
|
||||
</div>
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<input
|
||||
type="text"
|
||||
id="username"
|
||||
name="username"
|
||||
className={cx(props.kcInputClass)}
|
||||
autoFocus
|
||||
defaultValue={
|
||||
auth !== undefined && auth.showUsername
|
||||
? auth.attemptedUsername
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
return (
|
||||
<Template
|
||||
{...{ kcContext, ...props }}
|
||||
doFetchDefaultThemeResources={true}
|
||||
displayMessage={false}
|
||||
headerNode={msg("emailForgotTitle")}
|
||||
formNode={
|
||||
<form id="kc-reset-password-form" className={cx(props.kcFormClass)} action={url.loginAction} method="post">
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<div className={cx(props.kcLabelWrapperClass)}>
|
||||
<label htmlFor="username" className={cx(props.kcLabelClass)}>
|
||||
{!realm.loginWithEmailAllowed
|
||||
? msg("username")
|
||||
: !realm.registrationEmailAsUsername
|
||||
? msg("usernameOrEmail")
|
||||
: msg("email")}
|
||||
</label>
|
||||
</div>
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<input
|
||||
type="text"
|
||||
id="username"
|
||||
name="username"
|
||||
className={cx(props.kcInputClass)}
|
||||
autoFocus
|
||||
defaultValue={auth !== undefined && auth.showUsername ? auth.attemptedUsername : undefined}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className={cx(props.kcFormGroupClass, props.kcFormSettingClass)}>
|
||||
<div id="kc-form-options" className={cx(props.kcFormOptionsClass)}>
|
||||
<div className={cx(props.kcFormOptionsWrapperClass)}>
|
||||
<span>
|
||||
<a href={url.loginUrl}>{msg("backToLogin")}</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={cx(
|
||||
props.kcFormGroupClass,
|
||||
props.kcFormSettingClass,
|
||||
)}
|
||||
>
|
||||
<div
|
||||
id="kc-form-options"
|
||||
className={cx(props.kcFormOptionsClass)}
|
||||
>
|
||||
<div
|
||||
className={cx(
|
||||
props.kcFormOptionsWrapperClass,
|
||||
)}
|
||||
>
|
||||
<span>
|
||||
<a href={url.loginUrl}>
|
||||
{msg("backToLogin")}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="kc-form-buttons"
|
||||
className={cx(props.kcFormButtonsClass)}
|
||||
>
|
||||
<input
|
||||
className={cx(
|
||||
props.kcButtonClass,
|
||||
props.kcButtonPrimaryClass,
|
||||
props.kcButtonBlockClass,
|
||||
props.kcButtonLargeClass,
|
||||
)}
|
||||
type="submit"
|
||||
value={msgStr("doSubmit")}
|
||||
/>
|
||||
</div>
|
||||
<div id="kc-form-buttons" className={cx(props.kcFormButtonsClass)}>
|
||||
<input
|
||||
className={cx(props.kcButtonClass, props.kcButtonPrimaryClass, props.kcButtonBlockClass, props.kcButtonLargeClass)}
|
||||
type="submit"
|
||||
value={msgStr("doSubmit")}
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
infoNode={msg("emailInstruction")}
|
||||
/>
|
||||
);
|
||||
},
|
||||
);
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
infoNode={msg("emailInstruction")}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
@ -5,200 +5,116 @@ import type { KcContextBase } from "../getKcContext/KcContextBase";
|
||||
import { useKcMessage } from "../i18n/useKcMessage";
|
||||
import { useCssAndCx } from "tss-react";
|
||||
|
||||
export const LoginUpdateProfile = memo(
|
||||
({
|
||||
kcContext,
|
||||
...props
|
||||
}: { kcContext: KcContextBase.LoginUpdateProfile } & KcProps) => {
|
||||
const { cx } = useCssAndCx();
|
||||
export const LoginUpdateProfile = memo(({ kcContext, ...props }: { kcContext: KcContextBase.LoginUpdateProfile } & KcProps) => {
|
||||
const { cx } = useCssAndCx();
|
||||
|
||||
const { msg, msgStr } = useKcMessage();
|
||||
const { msg, msgStr } = useKcMessage();
|
||||
|
||||
const { url, user, messagesPerField, isAppInitiatedAction } = kcContext;
|
||||
const { url, user, messagesPerField, isAppInitiatedAction } = kcContext;
|
||||
|
||||
return (
|
||||
<Template
|
||||
{...{ kcContext, ...props }}
|
||||
doFetchDefaultThemeResources={true}
|
||||
headerNode={msg("loginProfileTitle")}
|
||||
formNode={
|
||||
<form
|
||||
id="kc-update-profile-form"
|
||||
className={cx(props.kcFormClass)}
|
||||
action={url.loginAction}
|
||||
method="post"
|
||||
>
|
||||
{user.editUsernameAllowed && (
|
||||
<div
|
||||
className={cx(
|
||||
props.kcFormGroupClass,
|
||||
messagesPerField.printIfExists(
|
||||
"username",
|
||||
props.kcFormGroupErrorClass,
|
||||
),
|
||||
)}
|
||||
>
|
||||
<div className={cx(props.kcLabelWrapperClass)}>
|
||||
<label
|
||||
htmlFor="username"
|
||||
className={cx(props.kcLabelClass)}
|
||||
>
|
||||
{msg("username")}
|
||||
</label>
|
||||
</div>
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
return (
|
||||
<Template
|
||||
{...{ kcContext, ...props }}
|
||||
doFetchDefaultThemeResources={true}
|
||||
headerNode={msg("loginProfileTitle")}
|
||||
formNode={
|
||||
<form id="kc-update-profile-form" className={cx(props.kcFormClass)} action={url.loginAction} method="post">
|
||||
{user.editUsernameAllowed && (
|
||||
<div className={cx(props.kcFormGroupClass, messagesPerField.printIfExists("username", props.kcFormGroupErrorClass))}>
|
||||
<div className={cx(props.kcLabelWrapperClass)}>
|
||||
<label htmlFor="username" className={cx(props.kcLabelClass)}>
|
||||
{msg("username")}
|
||||
</label>
|
||||
</div>
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<input
|
||||
type="text"
|
||||
id="username"
|
||||
name="username"
|
||||
defaultValue={user.username ?? ""}
|
||||
className={cx(props.kcInputClass)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className={cx(props.kcFormGroupClass, messagesPerField.printIfExists("email", props.kcFormGroupErrorClass))}>
|
||||
<div className={cx(props.kcLabelWrapperClass)}>
|
||||
<label htmlFor="email" className={cx(props.kcLabelClass)}>
|
||||
{msg("email")}
|
||||
</label>
|
||||
</div>
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<input type="text" id="email" name="email" defaultValue={user.email ?? ""} className={cx(props.kcInputClass)} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={cx(props.kcFormGroupClass, messagesPerField.printIfExists("firstName", props.kcFormGroupErrorClass))}>
|
||||
<div className={cx(props.kcLabelWrapperClass)}>
|
||||
<label htmlFor="firstName" className={cx(props.kcLabelClass)}>
|
||||
{msg("firstName")}
|
||||
</label>
|
||||
</div>
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<input
|
||||
type="text"
|
||||
id="firstName"
|
||||
name="firstName"
|
||||
defaultValue={user.firstName ?? ""}
|
||||
className={cx(props.kcInputClass)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={cx(props.kcFormGroupClass, messagesPerField.printIfExists("lastName", props.kcFormGroupErrorClass))}>
|
||||
<div className={cx(props.kcLabelWrapperClass)}>
|
||||
<label htmlFor="lastName" className={cx(props.kcLabelClass)}>
|
||||
{msg("lastName")}
|
||||
</label>
|
||||
</div>
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<input type="text" id="lastName" name="lastName" defaultValue={user.lastName ?? ""} className={cx(props.kcInputClass)} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<div id="kc-form-options" className={cx(props.kcFormOptionsClass)}>
|
||||
<div className={cx(props.kcFormOptionsWrapperClass)} />
|
||||
</div>
|
||||
|
||||
<div id="kc-form-buttons" className={cx(props.kcFormButtonsClass)}>
|
||||
{isAppInitiatedAction ? (
|
||||
<>
|
||||
<input
|
||||
type="text"
|
||||
id="username"
|
||||
name="username"
|
||||
defaultValue={user.username ?? ""}
|
||||
className={cx(props.kcInputClass)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div
|
||||
className={cx(
|
||||
props.kcFormGroupClass,
|
||||
messagesPerField.printIfExists(
|
||||
"email",
|
||||
props.kcFormGroupErrorClass,
|
||||
),
|
||||
)}
|
||||
>
|
||||
<div className={cx(props.kcLabelWrapperClass)}>
|
||||
<label
|
||||
htmlFor="email"
|
||||
className={cx(props.kcLabelClass)}
|
||||
>
|
||||
{msg("email")}
|
||||
</label>
|
||||
</div>
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<input
|
||||
type="text"
|
||||
id="email"
|
||||
name="email"
|
||||
defaultValue={user.email ?? ""}
|
||||
className={cx(props.kcInputClass)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={cx(
|
||||
props.kcFormGroupClass,
|
||||
messagesPerField.printIfExists(
|
||||
"firstName",
|
||||
props.kcFormGroupErrorClass,
|
||||
),
|
||||
)}
|
||||
>
|
||||
<div className={cx(props.kcLabelWrapperClass)}>
|
||||
<label
|
||||
htmlFor="firstName"
|
||||
className={cx(props.kcLabelClass)}
|
||||
>
|
||||
{msg("firstName")}
|
||||
</label>
|
||||
</div>
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<input
|
||||
type="text"
|
||||
id="firstName"
|
||||
name="firstName"
|
||||
defaultValue={user.firstName ?? ""}
|
||||
className={cx(props.kcInputClass)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={cx(
|
||||
props.kcFormGroupClass,
|
||||
messagesPerField.printIfExists(
|
||||
"lastName",
|
||||
props.kcFormGroupErrorClass,
|
||||
),
|
||||
)}
|
||||
>
|
||||
<div className={cx(props.kcLabelWrapperClass)}>
|
||||
<label
|
||||
htmlFor="lastName"
|
||||
className={cx(props.kcLabelClass)}
|
||||
>
|
||||
{msg("lastName")}
|
||||
</label>
|
||||
</div>
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<input
|
||||
type="text"
|
||||
id="lastName"
|
||||
name="lastName"
|
||||
defaultValue={user.lastName ?? ""}
|
||||
className={cx(props.kcInputClass)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<div
|
||||
id="kc-form-options"
|
||||
className={cx(props.kcFormOptionsClass)}
|
||||
>
|
||||
<div
|
||||
className={cx(
|
||||
props.kcFormOptionsWrapperClass,
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="kc-form-buttons"
|
||||
className={cx(props.kcFormButtonsClass)}
|
||||
>
|
||||
{isAppInitiatedAction ? (
|
||||
<>
|
||||
<input
|
||||
className={cx(
|
||||
props.kcButtonClass,
|
||||
props.kcButtonPrimaryClass,
|
||||
props.kcButtonLargeClass,
|
||||
)}
|
||||
type="submit"
|
||||
defaultValue={msgStr("doSubmit")}
|
||||
/>
|
||||
<button
|
||||
className={cx(
|
||||
props.kcButtonClass,
|
||||
props.kcButtonDefaultClass,
|
||||
props.kcButtonLargeClass,
|
||||
)}
|
||||
type="submit"
|
||||
name="cancel-aia"
|
||||
value="true"
|
||||
>
|
||||
{msg("doCancel")}
|
||||
</button>
|
||||
</>
|
||||
) : (
|
||||
<input
|
||||
className={cx(
|
||||
props.kcButtonClass,
|
||||
props.kcButtonPrimaryClass,
|
||||
props.kcButtonBlockClass,
|
||||
props.kcButtonLargeClass,
|
||||
)}
|
||||
className={cx(props.kcButtonClass, props.kcButtonPrimaryClass, props.kcButtonLargeClass)}
|
||||
type="submit"
|
||||
defaultValue={msgStr("doSubmit")}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<button
|
||||
className={cx(props.kcButtonClass, props.kcButtonDefaultClass, props.kcButtonLargeClass)}
|
||||
type="submit"
|
||||
name="cancel-aia"
|
||||
value="true"
|
||||
>
|
||||
{msg("doCancel")}
|
||||
</button>
|
||||
</>
|
||||
) : (
|
||||
<input
|
||||
className={cx(
|
||||
props.kcButtonClass,
|
||||
props.kcButtonPrimaryClass,
|
||||
props.kcButtonBlockClass,
|
||||
props.kcButtonLargeClass,
|
||||
)}
|
||||
type="submit"
|
||||
defaultValue={msgStr("doSubmit")}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
/>
|
||||
);
|
||||
},
|
||||
);
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
@ -4,34 +4,27 @@ import type { KcProps } from "./KcProps";
|
||||
import type { KcContextBase } from "../getKcContext/KcContextBase";
|
||||
import { useKcMessage } from "../i18n/useKcMessage";
|
||||
|
||||
export const LoginVerifyEmail = memo(
|
||||
({
|
||||
kcContext,
|
||||
...props
|
||||
}: { kcContext: KcContextBase.LoginVerifyEmail } & KcProps) => {
|
||||
const { msg } = useKcMessage();
|
||||
export const LoginVerifyEmail = memo(({ kcContext, ...props }: { kcContext: KcContextBase.LoginVerifyEmail } & KcProps) => {
|
||||
const { msg } = useKcMessage();
|
||||
|
||||
const { url } = kcContext;
|
||||
const { url } = kcContext;
|
||||
|
||||
return (
|
||||
<Template
|
||||
{...{ kcContext, ...props }}
|
||||
doFetchDefaultThemeResources={true}
|
||||
displayMessage={false}
|
||||
headerNode={msg("emailVerifyTitle")}
|
||||
formNode={
|
||||
<>
|
||||
<p className="instruction">
|
||||
{msg("emailVerifyInstruction1")}
|
||||
</p>
|
||||
<p className="instruction">
|
||||
{msg("emailVerifyInstruction2")}
|
||||
<a href={url.loginAction}>{msg("doClickHere")}</a>
|
||||
{msg("emailVerifyInstruction3")}
|
||||
</p>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
},
|
||||
);
|
||||
return (
|
||||
<Template
|
||||
{...{ kcContext, ...props }}
|
||||
doFetchDefaultThemeResources={true}
|
||||
displayMessage={false}
|
||||
headerNode={msg("emailVerifyTitle")}
|
||||
formNode={
|
||||
<>
|
||||
<p className="instruction">{msg("emailVerifyInstruction1")}</p>
|
||||
<p className="instruction">
|
||||
{msg("emailVerifyInstruction2")}
|
||||
<a href={url.loginAction}>{msg("doClickHere")}</a>
|
||||
{msg("emailVerifyInstruction3")}
|
||||
</p>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
@ -5,279 +5,152 @@ import type { KcContextBase } from "../getKcContext/KcContextBase";
|
||||
import { useKcMessage } from "../i18n/useKcMessage";
|
||||
import { useCssAndCx } from "tss-react";
|
||||
|
||||
export const Register = memo(
|
||||
({
|
||||
kcContext,
|
||||
...props
|
||||
}: { kcContext: KcContextBase.Register } & KcProps) => {
|
||||
const {
|
||||
url,
|
||||
messagesPerField,
|
||||
register,
|
||||
realm,
|
||||
passwordRequired,
|
||||
recaptchaRequired,
|
||||
recaptchaSiteKey,
|
||||
} = kcContext;
|
||||
export const Register = memo(({ kcContext, ...props }: { kcContext: KcContextBase.Register } & KcProps) => {
|
||||
const { url, messagesPerField, register, realm, passwordRequired, recaptchaRequired, recaptchaSiteKey } = kcContext;
|
||||
|
||||
const { msg, msgStr } = useKcMessage();
|
||||
const { msg, msgStr } = useKcMessage();
|
||||
|
||||
const { cx } = useCssAndCx();
|
||||
const { cx } = useCssAndCx();
|
||||
|
||||
return (
|
||||
<Template
|
||||
{...{ kcContext, ...props }}
|
||||
doFetchDefaultThemeResources={true}
|
||||
headerNode={msg("registerTitle")}
|
||||
formNode={
|
||||
<form
|
||||
id="kc-register-form"
|
||||
className={cx(props.kcFormClass)}
|
||||
action={url.registrationAction}
|
||||
method="post"
|
||||
>
|
||||
<div
|
||||
className={cx(
|
||||
props.kcFormGroupClass,
|
||||
messagesPerField.printIfExists(
|
||||
"firstName",
|
||||
props.kcFormGroupErrorClass,
|
||||
),
|
||||
)}
|
||||
>
|
||||
return (
|
||||
<Template
|
||||
{...{ kcContext, ...props }}
|
||||
doFetchDefaultThemeResources={true}
|
||||
headerNode={msg("registerTitle")}
|
||||
formNode={
|
||||
<form id="kc-register-form" className={cx(props.kcFormClass)} action={url.registrationAction} method="post">
|
||||
<div className={cx(props.kcFormGroupClass, messagesPerField.printIfExists("firstName", props.kcFormGroupErrorClass))}>
|
||||
<div className={cx(props.kcLabelWrapperClass)}>
|
||||
<label htmlFor="firstName" className={cx(props.kcLabelClass)}>
|
||||
{msg("firstName")}
|
||||
</label>
|
||||
</div>
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<input
|
||||
type="text"
|
||||
id="firstName"
|
||||
className={cx(props.kcInputClass)}
|
||||
name="firstName"
|
||||
defaultValue={register.formData.firstName ?? ""}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={cx(props.kcFormGroupClass, messagesPerField.printIfExists("lastName", props.kcFormGroupErrorClass))}>
|
||||
<div className={cx(props.kcLabelWrapperClass)}>
|
||||
<label htmlFor="lastName" className={cx(props.kcLabelClass)}>
|
||||
{msg("lastName")}
|
||||
</label>
|
||||
</div>
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<input
|
||||
type="text"
|
||||
id="lastName"
|
||||
className={cx(props.kcInputClass)}
|
||||
name="lastName"
|
||||
defaultValue={register.formData.lastName ?? ""}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={cx(props.kcFormGroupClass, messagesPerField.printIfExists("email", props.kcFormGroupErrorClass))}>
|
||||
<div className={cx(props.kcLabelWrapperClass)}>
|
||||
<label htmlFor="email" className={cx(props.kcLabelClass)}>
|
||||
{msg("email")}
|
||||
</label>
|
||||
</div>
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<input
|
||||
type="text"
|
||||
id="email"
|
||||
className={cx(props.kcInputClass)}
|
||||
name="email"
|
||||
defaultValue={register.formData.email ?? ""}
|
||||
autoComplete="email"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{!realm.registrationEmailAsUsername && (
|
||||
<div className={cx(props.kcFormGroupClass, messagesPerField.printIfExists("username", props.kcFormGroupErrorClass))}>
|
||||
<div className={cx(props.kcLabelWrapperClass)}>
|
||||
<label
|
||||
htmlFor="firstName"
|
||||
className={cx(props.kcLabelClass)}
|
||||
>
|
||||
{msg("firstName")}
|
||||
<label htmlFor="username" className={cx(props.kcLabelClass)}>
|
||||
{msg("username")}
|
||||
</label>
|
||||
</div>
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<input
|
||||
type="text"
|
||||
id="firstName"
|
||||
id="username"
|
||||
className={cx(props.kcInputClass)}
|
||||
name="firstName"
|
||||
defaultValue={
|
||||
register.formData.firstName ?? ""
|
||||
}
|
||||
name="username"
|
||||
defaultValue={register.formData.username ?? ""}
|
||||
autoComplete="username"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={cx(
|
||||
props.kcFormGroupClass,
|
||||
messagesPerField.printIfExists(
|
||||
"lastName",
|
||||
props.kcFormGroupErrorClass,
|
||||
),
|
||||
)}
|
||||
>
|
||||
<div className={cx(props.kcLabelWrapperClass)}>
|
||||
<label
|
||||
htmlFor="lastName"
|
||||
className={cx(props.kcLabelClass)}
|
||||
>
|
||||
{msg("lastName")}
|
||||
</label>
|
||||
</div>
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<input
|
||||
type="text"
|
||||
id="lastName"
|
||||
className={cx(props.kcInputClass)}
|
||||
name="lastName"
|
||||
defaultValue={
|
||||
register.formData.lastName ?? ""
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={cx(
|
||||
props.kcFormGroupClass,
|
||||
messagesPerField.printIfExists(
|
||||
"email",
|
||||
props.kcFormGroupErrorClass,
|
||||
),
|
||||
)}
|
||||
>
|
||||
<div className={cx(props.kcLabelWrapperClass)}>
|
||||
<label
|
||||
htmlFor="email"
|
||||
className={cx(props.kcLabelClass)}
|
||||
>
|
||||
{msg("email")}
|
||||
</label>
|
||||
</div>
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<input
|
||||
type="text"
|
||||
id="email"
|
||||
className={cx(props.kcInputClass)}
|
||||
name="email"
|
||||
defaultValue={register.formData.email ?? ""}
|
||||
autoComplete="email"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{!realm.registrationEmailAsUsername && (
|
||||
<div
|
||||
className={cx(
|
||||
props.kcFormGroupClass,
|
||||
messagesPerField.printIfExists(
|
||||
"username",
|
||||
props.kcFormGroupErrorClass,
|
||||
),
|
||||
)}
|
||||
>
|
||||
)}
|
||||
{passwordRequired && (
|
||||
<>
|
||||
<div className={cx(props.kcFormGroupClass, messagesPerField.printIfExists("password", props.kcFormGroupErrorClass))}>
|
||||
<div className={cx(props.kcLabelWrapperClass)}>
|
||||
<label
|
||||
htmlFor="username"
|
||||
className={cx(props.kcLabelClass)}
|
||||
>
|
||||
{msg("username")}
|
||||
<label htmlFor="password" className={cx(props.kcLabelClass)}>
|
||||
{msg("password")}
|
||||
</label>
|
||||
</div>
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<input
|
||||
type="text"
|
||||
id="username"
|
||||
type="password"
|
||||
id="password"
|
||||
className={cx(props.kcInputClass)}
|
||||
name="username"
|
||||
defaultValue={
|
||||
register.formData.username ?? ""
|
||||
}
|
||||
autoComplete="username"
|
||||
name="password"
|
||||
autoComplete="new-password"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{passwordRequired && (
|
||||
<>
|
||||
<div
|
||||
className={cx(
|
||||
props.kcFormGroupClass,
|
||||
messagesPerField.printIfExists(
|
||||
"password",
|
||||
props.kcFormGroupErrorClass,
|
||||
),
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={cx(
|
||||
props.kcLabelWrapperClass,
|
||||
)}
|
||||
>
|
||||
<label
|
||||
htmlFor="password"
|
||||
className={cx(props.kcLabelClass)}
|
||||
>
|
||||
{msg("password")}
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
className={cx(
|
||||
props.kcInputWrapperClass,
|
||||
)}
|
||||
>
|
||||
<input
|
||||
type="password"
|
||||
id="password"
|
||||
className={cx(props.kcInputClass)}
|
||||
name="password"
|
||||
autoComplete="new-password"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={cx(
|
||||
props.kcFormGroupClass,
|
||||
messagesPerField.printIfExists(
|
||||
"password-confirm",
|
||||
props.kcFormGroupErrorClass,
|
||||
),
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={cx(
|
||||
props.kcLabelWrapperClass,
|
||||
)}
|
||||
>
|
||||
<label
|
||||
htmlFor="password-confirm"
|
||||
className={cx(props.kcLabelClass)}
|
||||
>
|
||||
{msg("passwordConfirm")}
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
className={cx(
|
||||
props.kcInputWrapperClass,
|
||||
)}
|
||||
>
|
||||
<input
|
||||
type="password"
|
||||
id="password-confirm"
|
||||
className={cx(props.kcInputClass)}
|
||||
name="password-confirm"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={cx(
|
||||
props.kcFormGroupClass,
|
||||
messagesPerField.printIfExists("password-confirm", props.kcFormGroupErrorClass),
|
||||
)}
|
||||
>
|
||||
<div className={cx(props.kcLabelWrapperClass)}>
|
||||
<label htmlFor="password-confirm" className={cx(props.kcLabelClass)}>
|
||||
{msg("passwordConfirm")}
|
||||
</label>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{recaptchaRequired && (
|
||||
<div className="form-group">
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<div
|
||||
className="g-recaptcha"
|
||||
data-size="compact"
|
||||
data-sitekey={recaptchaSiteKey}
|
||||
></div>
|
||||
<input type="password" id="password-confirm" className={cx(props.kcInputClass)} name="password-confirm" />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<div
|
||||
id="kc-form-options"
|
||||
className={cx(props.kcFormOptionsClass)}
|
||||
>
|
||||
<div
|
||||
className={cx(
|
||||
props.kcFormOptionsWrapperClass,
|
||||
)}
|
||||
>
|
||||
<span>
|
||||
<a href={url.loginUrl}>
|
||||
{msg("backToLogin")}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="kc-form-buttons"
|
||||
className={cx(props.kcFormButtonsClass)}
|
||||
>
|
||||
<input
|
||||
className={cx(
|
||||
props.kcButtonClass,
|
||||
props.kcButtonPrimaryClass,
|
||||
props.kcButtonBlockClass,
|
||||
props.kcButtonLargeClass,
|
||||
)}
|
||||
type="submit"
|
||||
value={msgStr("doRegister")}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{recaptchaRequired && (
|
||||
<div className="form-group">
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<div className="g-recaptcha" data-size="compact" data-sitekey={recaptchaSiteKey}></div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
/>
|
||||
);
|
||||
},
|
||||
);
|
||||
)}
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<div id="kc-form-options" className={cx(props.kcFormOptionsClass)}>
|
||||
<div className={cx(props.kcFormOptionsWrapperClass)}>
|
||||
<span>
|
||||
<a href={url.loginUrl}>{msg("backToLogin")}</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="kc-form-buttons" className={cx(props.kcFormButtonsClass)}>
|
||||
<input
|
||||
className={cx(props.kcButtonClass, props.kcButtonPrimaryClass, props.kcButtonBlockClass, props.kcButtonLargeClass)}
|
||||
type="submit"
|
||||
value={msgStr("doRegister")}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
@ -6,216 +6,115 @@ import { useKcMessage } from "../i18n/useKcMessage";
|
||||
import { useCssAndCx } from "tss-react";
|
||||
import type { ReactComponent } from "../tools/ReactComponent";
|
||||
|
||||
export const RegisterUserProfile = memo(
|
||||
({
|
||||
kcContext,
|
||||
...props
|
||||
}: { kcContext: KcContextBase.RegisterUserProfile } & KcProps) => {
|
||||
const {
|
||||
url,
|
||||
messagesPerField,
|
||||
realm,
|
||||
passwordRequired,
|
||||
recaptchaRequired,
|
||||
recaptchaSiteKey,
|
||||
} = kcContext;
|
||||
export const RegisterUserProfile = memo(({ kcContext, ...props }: { kcContext: KcContextBase.RegisterUserProfile } & KcProps) => {
|
||||
const { url, messagesPerField, realm, passwordRequired, recaptchaRequired, recaptchaSiteKey } = kcContext;
|
||||
|
||||
const { msg, msgStr } = useKcMessage();
|
||||
const { msg, msgStr } = useKcMessage();
|
||||
|
||||
const { cx } = useCssAndCx();
|
||||
const { cx } = useCssAndCx();
|
||||
|
||||
return (
|
||||
<Template
|
||||
{...{ kcContext, ...props }}
|
||||
displayMessage={messagesPerField.exists("global")}
|
||||
displayRequiredFields={true}
|
||||
doFetchDefaultThemeResources={true}
|
||||
headerNode={msg("registerTitle")}
|
||||
formNode={
|
||||
<form
|
||||
id="kc-register-form"
|
||||
className={cx(props.kcFormClass)}
|
||||
action={url.registrationAction}
|
||||
method="post"
|
||||
>
|
||||
<UserProfileFormFields
|
||||
kcContext={kcContext}
|
||||
{...props}
|
||||
AfterField={({ attribute }) =>
|
||||
/*render password fields just under the username or email (if used as username)*/
|
||||
(passwordRequired &&
|
||||
(attribute.name == "username" ||
|
||||
(attribute.name == "email" &&
|
||||
realm.registrationEmailAsUsername)) && (
|
||||
<>
|
||||
<div
|
||||
className={cx(
|
||||
props.kcFormGroupClass,
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={cx(
|
||||
props.kcLabelWrapperClass,
|
||||
)}
|
||||
>
|
||||
<label
|
||||
htmlFor="password"
|
||||
className={cx(
|
||||
props.kcLabelClass,
|
||||
)}
|
||||
>
|
||||
{msg("password")}
|
||||
</label>{" "}
|
||||
*
|
||||
</div>
|
||||
<div
|
||||
className={cx(
|
||||
props.kcInputWrapperClass,
|
||||
)}
|
||||
>
|
||||
<input
|
||||
type="password"
|
||||
id="password"
|
||||
className={cx(
|
||||
props.kcInputClass,
|
||||
)}
|
||||
name="password"
|
||||
autoComplete="new-password"
|
||||
aria-invalid={
|
||||
messagesPerField.existsError(
|
||||
"password",
|
||||
) ||
|
||||
messagesPerField.existsError(
|
||||
"password-confirm",
|
||||
)
|
||||
}
|
||||
/>
|
||||
{messagesPerField.existsError(
|
||||
"password",
|
||||
) && (
|
||||
<span
|
||||
id="input-error-password"
|
||||
className={cx(
|
||||
props.kcInputErrorMessageClass,
|
||||
)}
|
||||
aria-live="polite"
|
||||
>
|
||||
{messagesPerField.get(
|
||||
"password",
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
return (
|
||||
<Template
|
||||
{...{ kcContext, ...props }}
|
||||
displayMessage={messagesPerField.exists("global")}
|
||||
displayRequiredFields={true}
|
||||
doFetchDefaultThemeResources={true}
|
||||
headerNode={msg("registerTitle")}
|
||||
formNode={
|
||||
<form id="kc-register-form" className={cx(props.kcFormClass)} action={url.registrationAction} method="post">
|
||||
<UserProfileFormFields
|
||||
kcContext={kcContext}
|
||||
{...props}
|
||||
AfterField={({ attribute }) =>
|
||||
/*render password fields just under the username or email (if used as username)*/
|
||||
(passwordRequired &&
|
||||
(attribute.name == "username" || (attribute.name == "email" && realm.registrationEmailAsUsername)) && (
|
||||
<>
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<div className={cx(props.kcLabelWrapperClass)}>
|
||||
<label htmlFor="password" className={cx(props.kcLabelClass)}>
|
||||
{msg("password")}
|
||||
</label>{" "}
|
||||
*
|
||||
</div>
|
||||
<div
|
||||
className={cx(
|
||||
props.kcFormGroupClass,
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<input
|
||||
type="password"
|
||||
id="password"
|
||||
className={cx(props.kcInputClass)}
|
||||
name="password"
|
||||
autoComplete="new-password"
|
||||
aria-invalid={
|
||||
messagesPerField.existsError("password") || messagesPerField.existsError("password-confirm")
|
||||
}
|
||||
/>
|
||||
{messagesPerField.existsError("password") && (
|
||||
<span id="input-error-password" className={cx(props.kcInputErrorMessageClass)} aria-live="polite">
|
||||
{messagesPerField.get("password")}
|
||||
</span>
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={cx(
|
||||
props.kcLabelWrapperClass,
|
||||
)}
|
||||
>
|
||||
<label
|
||||
htmlFor="password-confirm"
|
||||
className={cx(
|
||||
props.kcLabelClass,
|
||||
)}
|
||||
>
|
||||
{msg("passwordConfirm")}
|
||||
</label>{" "}
|
||||
*
|
||||
</div>
|
||||
<div
|
||||
className={cx(
|
||||
props.kcInputWrapperClass,
|
||||
)}
|
||||
>
|
||||
<input
|
||||
type="password"
|
||||
id="password-confirm"
|
||||
className={cx(
|
||||
props.kcInputClass,
|
||||
)}
|
||||
name="password-confirm"
|
||||
aria-invalid={messagesPerField.existsError(
|
||||
"password-confirm",
|
||||
)}
|
||||
/>
|
||||
{messagesPerField.existsError(
|
||||
"password-confirm",
|
||||
) && (
|
||||
<span
|
||||
id="input-error-password-confirm"
|
||||
className={cx(
|
||||
props.kcInputErrorMessageClass,
|
||||
)}
|
||||
aria-live="polite"
|
||||
>
|
||||
{messagesPerField.get(
|
||||
"password-confirm",
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)) ||
|
||||
null
|
||||
}
|
||||
/>
|
||||
{recaptchaRequired && (
|
||||
<div className="form-group">
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<div
|
||||
className="g-recaptcha"
|
||||
data-size="compact"
|
||||
data-sitekey={recaptchaSiteKey}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<div
|
||||
id="kc-form-options"
|
||||
className={cx(props.kcFormOptionsClass)}
|
||||
>
|
||||
<div
|
||||
className={cx(
|
||||
props.kcFormOptionsWrapperClass,
|
||||
)}
|
||||
>
|
||||
<span>
|
||||
<a href={url.loginUrl}>
|
||||
{msg("backToLogin")}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="kc-form-buttons"
|
||||
className={cx(props.kcFormButtonsClass)}
|
||||
>
|
||||
<input
|
||||
className={cx(
|
||||
props.kcButtonClass,
|
||||
props.kcButtonPrimaryClass,
|
||||
props.kcButtonBlockClass,
|
||||
props.kcButtonLargeClass,
|
||||
)}
|
||||
type="submit"
|
||||
value={msgStr("doRegister")}
|
||||
/>
|
||||
</div>
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<div className={cx(props.kcLabelWrapperClass)}>
|
||||
<label htmlFor="password-confirm" className={cx(props.kcLabelClass)}>
|
||||
{msg("passwordConfirm")}
|
||||
</label>{" "}
|
||||
*
|
||||
</div>
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<input
|
||||
type="password"
|
||||
id="password-confirm"
|
||||
className={cx(props.kcInputClass)}
|
||||
name="password-confirm"
|
||||
aria-invalid={messagesPerField.existsError("password-confirm")}
|
||||
/>
|
||||
{messagesPerField.existsError("password-confirm") && (
|
||||
<span
|
||||
id="input-error-password-confirm"
|
||||
className={cx(props.kcInputErrorMessageClass)}
|
||||
aria-live="polite"
|
||||
>
|
||||
{messagesPerField.get("password-confirm")}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)) ||
|
||||
null
|
||||
}
|
||||
/>
|
||||
{recaptchaRequired && (
|
||||
<div className="form-group">
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<div className="g-recaptcha" data-size="compact" data-sitekey={recaptchaSiteKey} />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
/>
|
||||
);
|
||||
},
|
||||
);
|
||||
)}
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<div id="kc-form-options" className={cx(props.kcFormOptionsClass)}>
|
||||
<div className={cx(props.kcFormOptionsWrapperClass)}>
|
||||
<span>
|
||||
<a href={url.loginUrl}>{msg("backToLogin")}</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="kc-form-buttons" className={cx(props.kcFormButtonsClass)}>
|
||||
<input
|
||||
className={cx(props.kcButtonClass, props.kcButtonPrimaryClass, props.kcButtonBlockClass, props.kcButtonLargeClass)}
|
||||
type="submit"
|
||||
value={msgStr("doRegister")}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
const UserProfileFormFields = memo(
|
||||
({
|
||||
@ -243,13 +142,11 @@ const UserProfileFormFields = memo(
|
||||
return (
|
||||
<>
|
||||
{kcContext.profile.attributes.map((attribute, i) => {
|
||||
const {
|
||||
group = "",
|
||||
groupDisplayHeader = "",
|
||||
groupDisplayDescription = "",
|
||||
} = attribute;
|
||||
const { group = "", groupDisplayHeader = "", groupDisplayDescription = "" } = attribute;
|
||||
|
||||
if (group === currentGroup) return null;
|
||||
console.log(JSON.stringify(attribute, null, 2));
|
||||
|
||||
//if (group === currentGroup) return null;
|
||||
|
||||
currentGroup = group;
|
||||
|
||||
@ -257,39 +154,15 @@ const UserProfileFormFields = memo(
|
||||
<Fragment key={i}>
|
||||
{group !== "" && (
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<div
|
||||
className={cx(
|
||||
props.kcContentWrapperClass,
|
||||
)}
|
||||
>
|
||||
<label
|
||||
id={`header-${group}`}
|
||||
className={cx(
|
||||
props.kcFormGroupHeader,
|
||||
)}
|
||||
>
|
||||
{(groupDisplayHeader !== "" &&
|
||||
advancedMsg(
|
||||
groupDisplayHeader,
|
||||
)) ||
|
||||
currentGroup}
|
||||
<div className={cx(props.kcContentWrapperClass)}>
|
||||
<label id={`header-${group}`} className={cx(props.kcFormGroupHeader)}>
|
||||
{(groupDisplayHeader !== "" && advancedMsg(groupDisplayHeader)) || currentGroup}
|
||||
</label>
|
||||
</div>
|
||||
{groupDisplayDescription !== "" && (
|
||||
<div
|
||||
className={cx(
|
||||
props.kcLabelWrapperClass,
|
||||
)}
|
||||
>
|
||||
<label
|
||||
id={`description-${group}`}
|
||||
className={`${cx(
|
||||
props.kcLabelClass,
|
||||
)}`}
|
||||
>
|
||||
{advancedMsg(
|
||||
groupDisplayDescription,
|
||||
) ?? ""}
|
||||
<div className={cx(props.kcLabelWrapperClass)}>
|
||||
<label id={`description-${group}`} className={`${cx(props.kcLabelClass)}`}>
|
||||
{advancedMsg(groupDisplayDescription) ?? ""}
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
@ -298,13 +171,8 @@ const UserProfileFormFields = memo(
|
||||
<BeforeField attribute={attribute} />
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<div className={cx(props.kcLabelWrapperClass)}>
|
||||
<label
|
||||
htmlFor={attribute.name}
|
||||
className={cx(props.kcLabelClass)}
|
||||
>
|
||||
{advancedMsg(
|
||||
attribute.displayName ?? "",
|
||||
)}
|
||||
<label htmlFor={attribute.name} className={cx(props.kcLabelClass)}>
|
||||
{advancedMsg(attribute.displayName ?? "")}
|
||||
</label>
|
||||
{attribute.required && <>*</>}
|
||||
</div>
|
||||
@ -313,33 +181,19 @@ const UserProfileFormFields = memo(
|
||||
type="text"
|
||||
id={attribute.name}
|
||||
name={attribute.name}
|
||||
value={attribute.value ?? ""}
|
||||
defaultValue={attribute.value ?? ""}
|
||||
className={cx(props.kcInputClass)}
|
||||
aria-invalid={messagesPerField.existsError(
|
||||
attribute.name,
|
||||
)}
|
||||
aria-invalid={messagesPerField.existsError(attribute.name)}
|
||||
disabled={attribute.readOnly}
|
||||
{...(attribute.autocomplete ===
|
||||
undefined
|
||||
{...(attribute.autocomplete === undefined
|
||||
? {}
|
||||
: {
|
||||
"autoComplete":
|
||||
attribute.autocomplete,
|
||||
"autoComplete": attribute.autocomplete,
|
||||
})}
|
||||
/>
|
||||
{kcContext.messagesPerField.existsError(
|
||||
attribute.name,
|
||||
) && (
|
||||
<span
|
||||
id={`input-error-${attribute.name}`}
|
||||
className={cx(
|
||||
props.kcInputErrorMessageClass,
|
||||
)}
|
||||
aria-live="polite"
|
||||
>
|
||||
{messagesPerField.get(
|
||||
attribute.name,
|
||||
)}
|
||||
{kcContext.messagesPerField.existsError(attribute.name) && (
|
||||
<span id={`input-error-${attribute.name}`} className={cx(props.kcInputErrorMessageClass)} aria-live="polite">
|
||||
{messagesPerField.get(attribute.name)}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
@ -55,19 +55,11 @@ export const Template = memo((props: TemplateProps) => {
|
||||
|
||||
const { kcLanguageTag, setKcLanguageTag } = useKcLanguageTag();
|
||||
|
||||
const onChangeLanguageClickFactory = useCallbackFactory(
|
||||
([languageTag]: [KcLanguageTag]) => setKcLanguageTag(languageTag),
|
||||
);
|
||||
const onChangeLanguageClickFactory = useCallbackFactory(([languageTag]: [KcLanguageTag]) => setKcLanguageTag(languageTag));
|
||||
|
||||
const onTryAnotherWayClick = useConstCallback(
|
||||
() => (
|
||||
document.forms["kc-select-try-another-way-form" as never].submit(),
|
||||
false
|
||||
),
|
||||
);
|
||||
const onTryAnotherWayClick = useConstCallback(() => (document.forms["kc-select-try-another-way-form" as never].submit(), false));
|
||||
|
||||
const { realm, locale, auth, url, message, isAppInitiatedAction } =
|
||||
kcContext;
|
||||
const { realm, locale, auth, url, message, isAppInitiatedAction } = kcContext;
|
||||
|
||||
useEffect(() => {
|
||||
if (!realm.internationalizationEnabled) {
|
||||
@ -80,9 +72,7 @@ export const Template = memo((props: TemplateProps) => {
|
||||
return;
|
||||
}
|
||||
|
||||
window.location.href = locale.supported.find(
|
||||
({ languageTag }) => languageTag === kcLanguageTag,
|
||||
)!.url;
|
||||
window.location.href = locale.supported.find(({ languageTag }) => languageTag === kcLanguageTag)!.url;
|
||||
}, [kcLanguageTag]);
|
||||
|
||||
const [isExtraCssLoaded, setExtraCssLoaded] = useReducer(() => true, false);
|
||||
@ -96,17 +86,12 @@ export const Template = memo((props: TemplateProps) => {
|
||||
let isUnmounted = false;
|
||||
const cleanups: (() => void)[] = [];
|
||||
|
||||
const toArr = (x: string | readonly string[] | undefined) =>
|
||||
typeof x === "string" ? x.split(" ") : x ?? [];
|
||||
const toArr = (x: string | readonly string[] | undefined) => (typeof x === "string" ? x.split(" ") : x ?? []);
|
||||
|
||||
Promise.all(
|
||||
[
|
||||
...toArr(props.stylesCommon).map(relativePath =>
|
||||
pathJoin(url.resourcesCommonPath, relativePath),
|
||||
),
|
||||
...toArr(props.styles).map(relativePath =>
|
||||
pathJoin(url.resourcesPath, relativePath),
|
||||
),
|
||||
...toArr(props.stylesCommon).map(relativePath => pathJoin(url.resourcesCommonPath, relativePath)),
|
||||
...toArr(props.styles).map(relativePath => pathJoin(url.resourcesPath, relativePath)),
|
||||
].map(href =>
|
||||
appendHead({
|
||||
"type": "css",
|
||||
@ -129,8 +114,7 @@ export const Template = memo((props: TemplateProps) => {
|
||||
);
|
||||
|
||||
if (props.kcHtmlClass !== undefined) {
|
||||
const htmlClassList =
|
||||
document.getElementsByTagName("html")[0].classList;
|
||||
const htmlClassList = document.getElementsByTagName("html")[0].classList;
|
||||
|
||||
const tokens = cx(props.kcHtmlClass).split(" ");
|
||||
|
||||
@ -153,76 +137,37 @@ export const Template = memo((props: TemplateProps) => {
|
||||
return (
|
||||
<div className={cx(props.kcLoginClass)}>
|
||||
<div id="kc-header" className={cx(props.kcHeaderClass)}>
|
||||
<div
|
||||
id="kc-header-wrapper"
|
||||
className={cx(props.kcHeaderWrapperClass)}
|
||||
>
|
||||
<div id="kc-header-wrapper" className={cx(props.kcHeaderWrapperClass)}>
|
||||
{msg("loginTitleHtml", realm.displayNameHtml)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={cx(
|
||||
props.kcFormCardClass,
|
||||
displayWide && props.kcFormCardAccountClass,
|
||||
)}
|
||||
>
|
||||
<div className={cx(props.kcFormCardClass, displayWide && props.kcFormCardAccountClass)}>
|
||||
<header className={cx(props.kcFormHeaderClass)}>
|
||||
{realm.internationalizationEnabled &&
|
||||
(assert(locale !== undefined), true) &&
|
||||
locale.supported.length > 1 && (
|
||||
<div id="kc-locale">
|
||||
<div
|
||||
id="kc-locale-wrapper"
|
||||
className={cx(props.kcLocaleWrapperClass)}
|
||||
>
|
||||
<div
|
||||
className="kc-dropdown"
|
||||
id="kc-locale-dropdown"
|
||||
>
|
||||
<a href="#" id="kc-current-locale-link">
|
||||
{getKcLanguageTagLabel(
|
||||
kcLanguageTag,
|
||||
)}
|
||||
</a>
|
||||
<ul>
|
||||
{locale.supported.map(
|
||||
({ languageTag }) => (
|
||||
<li
|
||||
key={languageTag}
|
||||
className="kc-dropdown-item"
|
||||
>
|
||||
<a
|
||||
href="#"
|
||||
onClick={onChangeLanguageClickFactory(
|
||||
languageTag,
|
||||
)}
|
||||
>
|
||||
{getKcLanguageTagLabel(
|
||||
languageTag,
|
||||
)}
|
||||
</a>
|
||||
</li>
|
||||
),
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
{realm.internationalizationEnabled && (assert(locale !== undefined), true) && locale.supported.length > 1 && (
|
||||
<div id="kc-locale">
|
||||
<div id="kc-locale-wrapper" className={cx(props.kcLocaleWrapperClass)}>
|
||||
<div className="kc-dropdown" id="kc-locale-dropdown">
|
||||
<a href="#" id="kc-current-locale-link">
|
||||
{getKcLanguageTagLabel(kcLanguageTag)}
|
||||
</a>
|
||||
<ul>
|
||||
{locale.supported.map(({ languageTag }) => (
|
||||
<li key={languageTag} className="kc-dropdown-item">
|
||||
<a href="#" onClick={onChangeLanguageClickFactory(languageTag)}>
|
||||
{getKcLanguageTagLabel(languageTag)}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{!(
|
||||
auth !== undefined &&
|
||||
auth.showUsername &&
|
||||
!auth.showResetCredentials
|
||||
) ? (
|
||||
</div>
|
||||
)}
|
||||
{!(auth !== undefined && auth.showUsername && !auth.showResetCredentials) ? (
|
||||
displayRequiredFields ? (
|
||||
<div className={cx(props.kcContentWrapperClass)}>
|
||||
<div
|
||||
className={cx(
|
||||
props.kcLabelWrapperClass,
|
||||
"subtitle",
|
||||
)}
|
||||
>
|
||||
<div className={cx(props.kcLabelWrapperClass, "subtitle")}>
|
||||
<span className="subtitle">
|
||||
<span className="required">*</span>
|
||||
{msg("requiredFields")}
|
||||
@ -237,37 +182,20 @@ export const Template = memo((props: TemplateProps) => {
|
||||
)
|
||||
) : displayRequiredFields ? (
|
||||
<div className={cx(props.kcContentWrapperClass)}>
|
||||
<div
|
||||
className={cx(
|
||||
props.kcLabelWrapperClass,
|
||||
"subtitle",
|
||||
)}
|
||||
>
|
||||
<div className={cx(props.kcLabelWrapperClass, "subtitle")}>
|
||||
<span className="subtitle">
|
||||
<span className="required">*</span>{" "}
|
||||
{msg("requiredFields")}
|
||||
<span className="required">*</span> {msg("requiredFields")}
|
||||
</span>
|
||||
</div>
|
||||
<div className="col-md-10">
|
||||
{showUsernameNode}
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<div id="kc-username">
|
||||
<label id="kc-attempted-username">
|
||||
{auth?.attemptedUsername}
|
||||
</label>
|
||||
<a
|
||||
id="reset-login"
|
||||
href={url.loginRestartFlowUrl}
|
||||
>
|
||||
<label id="kc-attempted-username">{auth?.attemptedUsername}</label>
|
||||
<a id="reset-login" href={url.loginRestartFlowUrl}>
|
||||
<div className="kc-login-tooltip">
|
||||
<i
|
||||
className={cx(
|
||||
props.kcResetFlowIcon,
|
||||
)}
|
||||
></i>
|
||||
<span className="kc-tooltip-text">
|
||||
{msg("restartLoginTooltip")}
|
||||
</span>
|
||||
<i className={cx(props.kcResetFlowIcon)}></i>
|
||||
<span className="kc-tooltip-text">{msg("restartLoginTooltip")}</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
@ -279,22 +207,11 @@ export const Template = memo((props: TemplateProps) => {
|
||||
{showUsernameNode}
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<div id="kc-username">
|
||||
<label id="kc-attempted-username">
|
||||
{auth?.attemptedUsername}
|
||||
</label>
|
||||
<a
|
||||
id="reset-login"
|
||||
href={url.loginRestartFlowUrl}
|
||||
>
|
||||
<label id="kc-attempted-username">{auth?.attemptedUsername}</label>
|
||||
<a id="reset-login" href={url.loginRestartFlowUrl}>
|
||||
<div className="kc-login-tooltip">
|
||||
<i
|
||||
className={cx(
|
||||
props.kcResetFlowIcon,
|
||||
)}
|
||||
></i>
|
||||
<span className="kc-tooltip-text">
|
||||
{msg("restartLoginTooltip")}
|
||||
</span>
|
||||
<i className={cx(props.kcResetFlowIcon)}></i>
|
||||
<span className="kc-tooltip-text">{msg("restartLoginTooltip")}</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
@ -305,103 +222,41 @@ export const Template = memo((props: TemplateProps) => {
|
||||
<div id="kc-content">
|
||||
<div id="kc-content-wrapper">
|
||||
{/* App-initiated actions should not see warning messages about the need to complete the action during login. */}
|
||||
{displayMessage &&
|
||||
message !== undefined &&
|
||||
(message.type !== "warning" ||
|
||||
!isAppInitiatedAction) && (
|
||||
<div
|
||||
className={cx(
|
||||
"alert",
|
||||
`alert-${message.type}`,
|
||||
)}
|
||||
>
|
||||
{message.type === "success" && (
|
||||
<span
|
||||
className={cx(
|
||||
props.kcFeedbackSuccessIcon,
|
||||
)}
|
||||
></span>
|
||||
)}
|
||||
{message.type === "warning" && (
|
||||
<span
|
||||
className={cx(
|
||||
props.kcFeedbackWarningIcon,
|
||||
)}
|
||||
></span>
|
||||
)}
|
||||
{message.type === "error" && (
|
||||
<span
|
||||
className={cx(
|
||||
props.kcFeedbackErrorIcon,
|
||||
)}
|
||||
></span>
|
||||
)}
|
||||
{message.type === "info" && (
|
||||
<span
|
||||
className={cx(
|
||||
props.kcFeedbackInfoIcon,
|
||||
)}
|
||||
></span>
|
||||
)}
|
||||
<span
|
||||
className="kc-feedback-text"
|
||||
dangerouslySetInnerHTML={{
|
||||
"__html": message.summary,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{displayMessage && message !== undefined && (message.type !== "warning" || !isAppInitiatedAction) && (
|
||||
<div className={cx("alert", `alert-${message.type}`)}>
|
||||
{message.type === "success" && <span className={cx(props.kcFeedbackSuccessIcon)}></span>}
|
||||
{message.type === "warning" && <span className={cx(props.kcFeedbackWarningIcon)}></span>}
|
||||
{message.type === "error" && <span className={cx(props.kcFeedbackErrorIcon)}></span>}
|
||||
{message.type === "info" && <span className={cx(props.kcFeedbackInfoIcon)}></span>}
|
||||
<span
|
||||
className="kc-feedback-text"
|
||||
dangerouslySetInnerHTML={{
|
||||
"__html": message.summary,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{formNode}
|
||||
{auth !== undefined &&
|
||||
auth.showTryAnotherWayLink &&
|
||||
showAnotherWayIfPresent && (
|
||||
<form
|
||||
id="kc-select-try-another-way-form"
|
||||
action={url.loginAction}
|
||||
method="post"
|
||||
className={cx(
|
||||
displayWide &&
|
||||
props.kcContentWrapperClass,
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={cx(
|
||||
displayWide && [
|
||||
props.kcFormSocialAccountContentClass,
|
||||
props.kcFormSocialAccountClass,
|
||||
],
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={cx(
|
||||
props.kcFormGroupClass,
|
||||
)}
|
||||
>
|
||||
<input
|
||||
type="hidden"
|
||||
name="tryAnotherWay"
|
||||
value="on"
|
||||
/>
|
||||
<a
|
||||
href="#"
|
||||
id="try-another-way"
|
||||
onClick={onTryAnotherWayClick}
|
||||
>
|
||||
{msg("doTryAnotherWay")}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
)}
|
||||
{displayInfo && (
|
||||
<div
|
||||
id="kc-info"
|
||||
className={cx(props.kcSignUpClass)}
|
||||
{auth !== undefined && auth.showTryAnotherWayLink && showAnotherWayIfPresent && (
|
||||
<form
|
||||
id="kc-select-try-another-way-form"
|
||||
action={url.loginAction}
|
||||
method="post"
|
||||
className={cx(displayWide && props.kcContentWrapperClass)}
|
||||
>
|
||||
<div
|
||||
id="kc-info-wrapper"
|
||||
className={cx(props.kcInfoAreaWrapperClass)}
|
||||
>
|
||||
<div className={cx(displayWide && [props.kcFormSocialAccountContentClass, props.kcFormSocialAccountClass])}>
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<input type="hidden" name="tryAnotherWay" value="on" />
|
||||
<a href="#" id="try-another-way" onClick={onTryAnotherWayClick}>
|
||||
{msg("doTryAnotherWay")}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
)}
|
||||
{displayInfo && (
|
||||
<div id="kc-info" className={cx(props.kcSignUpClass)}>
|
||||
<div id="kc-info-wrapper" className={cx(props.kcInfoAreaWrapperClass)}>
|
||||
{infoNode}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -5,57 +5,47 @@ import type { KcContextBase } from "../getKcContext/KcContextBase";
|
||||
import { useKcMessage } from "../i18n/useKcMessage";
|
||||
import { useCssAndCx } from "tss-react";
|
||||
|
||||
export const Terms = memo(
|
||||
({ kcContext, ...props }: { kcContext: KcContextBase.Terms } & KcProps) => {
|
||||
const { msg, msgStr } = useKcMessage();
|
||||
export const Terms = memo(({ kcContext, ...props }: { kcContext: KcContextBase.Terms } & KcProps) => {
|
||||
const { msg, msgStr } = useKcMessage();
|
||||
|
||||
const { cx } = useCssAndCx();
|
||||
const { cx } = useCssAndCx();
|
||||
|
||||
const { url } = kcContext;
|
||||
const { url } = kcContext;
|
||||
|
||||
return (
|
||||
<Template
|
||||
{...{ kcContext, ...props }}
|
||||
doFetchDefaultThemeResources={true}
|
||||
displayMessage={false}
|
||||
headerNode={msg("termsTitle")}
|
||||
formNode={
|
||||
<>
|
||||
<div id="kc-terms-text">{msg("termsText")}</div>
|
||||
<form
|
||||
className="form-actions"
|
||||
action={url.loginAction}
|
||||
method="POST"
|
||||
>
|
||||
<input
|
||||
className={cx(
|
||||
props.kcButtonClass,
|
||||
props.kcButtonClass,
|
||||
props.kcButtonClass,
|
||||
props.kcButtonPrimaryClass,
|
||||
props.kcButtonLargeClass,
|
||||
)}
|
||||
name="accept"
|
||||
id="kc-accept"
|
||||
type="submit"
|
||||
value={msgStr("doAccept")}
|
||||
/>
|
||||
<input
|
||||
className={cx(
|
||||
props.kcButtonClass,
|
||||
props.kcButtonDefaultClass,
|
||||
props.kcButtonLargeClass,
|
||||
)}
|
||||
name="cancel"
|
||||
id="kc-decline"
|
||||
type="submit"
|
||||
value={msgStr("doDecline")}
|
||||
/>
|
||||
</form>
|
||||
<div className="clearfix" />
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
},
|
||||
);
|
||||
return (
|
||||
<Template
|
||||
{...{ kcContext, ...props }}
|
||||
doFetchDefaultThemeResources={true}
|
||||
displayMessage={false}
|
||||
headerNode={msg("termsTitle")}
|
||||
formNode={
|
||||
<>
|
||||
<div id="kc-terms-text">{msg("termsText")}</div>
|
||||
<form className="form-actions" action={url.loginAction} method="POST">
|
||||
<input
|
||||
className={cx(
|
||||
props.kcButtonClass,
|
||||
props.kcButtonClass,
|
||||
props.kcButtonClass,
|
||||
props.kcButtonPrimaryClass,
|
||||
props.kcButtonLargeClass,
|
||||
)}
|
||||
name="accept"
|
||||
id="kc-accept"
|
||||
type="submit"
|
||||
value={msgStr("doAccept")}
|
||||
/>
|
||||
<input
|
||||
className={cx(props.kcButtonClass, props.kcButtonDefaultClass, props.kcButtonLargeClass)}
|
||||
name="cancel"
|
||||
id="kc-decline"
|
||||
type="submit"
|
||||
value={msgStr("doDecline")}
|
||||
/>
|
||||
</form>
|
||||
<div className="clearfix" />
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
Reference in New Issue
Block a user