Implement login-reset-password.ftl

This commit is contained in:
Joseph Garrone 2021-03-07 14:57:53 +01:00
parent 85fdaa2f22
commit 740d9b7af5
6 changed files with 109 additions and 7 deletions

View File

@ -9,7 +9,7 @@ import fs from "fs";
import { join as pathJoin } from "path"; import { join as pathJoin } from "path";
import { objectKeys } from "evt/tools/typeSafety/objectKeys"; import { objectKeys } from "evt/tools/typeSafety/objectKeys";
export const pageIds= [ "login.ftl", "register.ftl", "info.ftl", "error.ftl"] as const; export const pageIds= [ "login.ftl", "register.ftl", "info.ftl", "error.ftl", "login-reset-password.ftl"] as const;
export type PageId = typeof pageIds[number]; export type PageId = typeof pageIds[number];

View File

@ -0,0 +1,7 @@
<script>const _=
{
"realm": {
"loginWithEmailAllowed": ${realm.loginWithEmailAllowed?c}
},
}
</script>

View File

@ -6,7 +6,8 @@ import type { KcProps } from "./KcProps";
import { Login } from "./Login"; import { Login } from "./Login";
import { Register } from "./Register"; import { Register } from "./Register";
import { Info } from "./Info"; import { Info } from "./Info";
import { Error } from "./Error"; import { Error } from "./Error";
import { LoginResetPassword } from "./LoginResetPassword";
export const KcApp = memo((props: KcProps) => { export const KcApp = memo((props: KcProps) => {
@ -18,6 +19,7 @@ export const KcApp = memo((props: KcProps) => {
case "register.ftl": return <Register {...props} />; case "register.ftl": return <Register {...props} />;
case "info.ftl": return <Info {...props} />; case "info.ftl": return <Info {...props} />;
case "error.ftl": return <Error {...props} />; case "error.ftl": return <Error {...props} />;
case "login-reset-password.ftl": return <LoginResetPassword {...props} />;
} }
}); });

View File

@ -0,0 +1,86 @@
import { memo } from "react";
import { Template } from "./Template";
import type { KcProps } from "./KcProps";
import { assert } from "../tools/assert";
import { kcContext } from "../kcContext";
import { useKcTranslation } from "../i18n/useKcTranslation";
import { cx } from "tss-react";
export const LoginResetPassword = memo((props: KcProps) => {
const { t, tStr } = useKcTranslation();
assert(
kcContext !== undefined &&
kcContext.pageId === "login-reset-password.ftl"
);
const {
url,
realm,
auth
} = kcContext;
return (
<Template
{...props}
displayMessage={false}
headerNode={t("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 ?
t("username")
:
!realm.registrationEmailAsUsername ?
t("usernameOrEmail") :
t("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}>{t("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"
defaultValue={tStr("doSubmit")}
/>
</div>
</div>
</form>
}
infoNode={t("emailInstruction")}
/>
);
});

View File

@ -24,7 +24,7 @@ export type TemplateProps = {
headerNode: ReactNode; headerNode: ReactNode;
showUsernameNode?: ReactNode; showUsernameNode?: ReactNode;
formNode: ReactNode; formNode: ReactNode;
displayInfoNode?: ReactNode; infoNode?: ReactNode;
} & KcTemplateProps; } & KcTemplateProps;
@ -39,7 +39,7 @@ export const Template = memo((props: TemplateProps) => {
headerNode, headerNode,
showUsernameNode = null, showUsernameNode = null,
formNode, formNode,
displayInfoNode = null infoNode = null
} = props; } = props;
useEffect(() => { console.log("Rendering this page with react using keycloakify") }, []); useEffect(() => { console.log("Rendering this page with react using keycloakify") }, []);
@ -279,7 +279,7 @@ export const Template = memo((props: TemplateProps) => {
<div id="kc-info" className={cx(props.kcSignUpClass)}> <div id="kc-info" className={cx(props.kcSignUpClass)}>
<div id="kc-info-wrapper" className={cx(props.kcInfoAreaWrapperClass)}> <div id="kc-info-wrapper" className={cx(props.kcInfoAreaWrapperClass)}>
{displayInfoNode} {infoNode}
</div> </div>
</div> </div>
} }

View File

@ -10,7 +10,7 @@ import type { LanguageLabel } from "./i18n/KcLanguageTag";
type ExtractAfterStartingWith<Prefix extends string, StrEnum> = type ExtractAfterStartingWith<Prefix extends string, StrEnum> =
StrEnum extends `${Prefix}${infer U}` ? U : never; StrEnum extends `${Prefix}${infer U}` ? U : never;
export type KcContext = KcContext.Login | KcContext.Register | KcContext.Info | KcContext.Error; export type KcContext = KcContext.Login | KcContext.Register | KcContext.Info | KcContext.Error | KcContext.LoginResetPassword;
export declare namespace KcContext { export declare namespace KcContext {
export type Template = { export type Template = {
@ -43,7 +43,7 @@ export declare namespace KcContext {
showUsername: boolean; showUsername: boolean;
showResetCredentials: boolean; showResetCredentials: boolean;
showTryAnotherWayLink: boolean; showTryAnotherWayLink: boolean;
attemptedUsername?: boolean; attemptedUsername?: string;
}; };
scripts: string[]; scripts: string[];
message?: { message?: {
@ -138,6 +138,13 @@ export declare namespace KcContext {
} }
}; };
export type LoginResetPassword = Template & {
pageId: "login-reset-password.ftl";
realm: {
loginWithEmailAllowed: boolean;
}
};
} }
doExtends<KcContext["pageId"], PageId>(); doExtends<KcContext["pageId"], PageId>();