diff --git a/src/bin/keycloakify/generateFtl/generateFtl.ts b/src/bin/keycloakify/generateFtl/generateFtl.ts index 0f5dd1ff..f13f5cd7 100644 --- a/src/bin/keycloakify/generateFtl/generateFtl.ts +++ b/src/bin/keycloakify/generateFtl/generateFtl.ts @@ -35,7 +35,8 @@ export const loginThemePageIds = [ "login-config-totp.ftl", "logout-confirm.ftl", "update-user-profile.ftl", - "idp-review-user-profile.ftl" + "idp-review-user-profile.ftl", + "update-email.ftl" ] as const; export const accountThemePageIds = ["password.ftl", "account.ftl"] as const; diff --git a/src/login/Fallback.tsx b/src/login/Fallback.tsx index 80124987..413040c1 100644 --- a/src/login/Fallback.tsx +++ b/src/login/Fallback.tsx @@ -25,6 +25,7 @@ const LoginConfigTotp = lazy(() => import("keycloakify/login/pages/LoginConfigTo const LogoutConfirm = lazy(() => import("keycloakify/login/pages/LogoutConfirm")); const UpdateUserProfile = lazy(() => import("keycloakify/login/pages/UpdateUserProfile")); const IdpReviewUserProfile = lazy(() => import("keycloakify/login/pages/IdpReviewUserProfile")); +const UpdateEmail = lazy(() => import("keycloakify/login/pages/UpdateEmail")); export default function Fallback(props: PageProps) { const { kcContext, ...rest } = props; @@ -75,6 +76,8 @@ export default function Fallback(props: PageProps) { return ; case "idp-review-user-profile.ftl": return ; + case "update-email.ftl": + return ; } assert>(false); })()} diff --git a/src/login/kcContext/KcContext.ts b/src/login/kcContext/KcContext.ts index 271cffba..475154f9 100644 --- a/src/login/kcContext/KcContext.ts +++ b/src/login/kcContext/KcContext.ts @@ -30,7 +30,8 @@ export type KcContext = | KcContext.LoginConfigTotp | KcContext.LogoutConfirm | KcContext.UpdateUserProfile - | KcContext.IdpReviewUserProfile; + | KcContext.IdpReviewUserProfile + | KcContext.UpdateEmail; export declare namespace KcContext { export type Common = { @@ -381,6 +382,13 @@ export declare namespace KcContext { attributesByName: Record; }; }; + + export type UpdateEmail = Common & { + pageId: "update-email.ftl"; + email: { + value?: string; + }; + }; } export type Attribute = { diff --git a/src/login/kcContext/kcContextMocks.ts b/src/login/kcContext/kcContextMocks.ts index 02a156a0..ebfd908c 100644 --- a/src/login/kcContext/kcContextMocks.ts +++ b/src/login/kcContext/kcContextMocks.ts @@ -491,5 +491,12 @@ export const kcContextMocks: KcContext[] = [ attributes, attributesByName } + }), + id({ + ...kcContextCommonMock, + "pageId": "update-email.ftl", + "email": { + value: "email@example.com" + } }) ]; diff --git a/src/login/pages/UpdateEmail.tsx b/src/login/pages/UpdateEmail.tsx new file mode 100644 index 00000000..be669b21 --- /dev/null +++ b/src/login/pages/UpdateEmail.tsx @@ -0,0 +1,88 @@ +import { clsx } from "keycloakify/tools/clsx"; +import type { PageProps } from "keycloakify/login/pages/PageProps"; +import { useGetClassName } from "keycloakify/login/lib/useGetClassName"; +import type { KcContext } from "../kcContext"; +import type { I18n } from "../i18n"; + +export default function UpdateEmail(props: PageProps, I18n>) { + const { kcContext, i18n, doUseDefaultCss, Template, classes } = props; + + const { getClassName } = useGetClassName({ + doUseDefaultCss, + classes + }); + + const { msg, msgStr } = i18n; + + const { url, messagesPerField, isAppInitiatedAction, email } = kcContext; + + return ( + + ); +}