diff --git a/src/bin/build-keycloak-theme/generateFtl/index.ts b/src/bin/build-keycloak-theme/generateFtl/index.ts index 65ba9a8d..08ae61d5 100644 --- a/src/bin/build-keycloak-theme/generateFtl/index.ts +++ b/src/bin/build-keycloak-theme/generateFtl/index.ts @@ -14,7 +14,8 @@ import { ftlValuesGlobalName } from "../ftlValuesGlobalName"; export const pageIds = [ "login.ftl", "register.ftl", "info.ftl", "error.ftl", "login-reset-password.ftl", - "login-verify-email.ftl", "terms.ftl" + "login-verify-email.ftl", "terms.ftl", + "login-otp.ftl" ] as const; export type PageId = typeof pageIds[number]; diff --git a/src/bin/build-keycloak-theme/generateFtl/login-otp.ftl b/src/bin/build-keycloak-theme/generateFtl/login-otp.ftl new file mode 100644 index 00000000..a2cc9e41 --- /dev/null +++ b/src/bin/build-keycloak-theme/generateFtl/login-otp.ftl @@ -0,0 +1,37 @@ + \ No newline at end of file diff --git a/src/lib/components/KcApp.tsx b/src/lib/components/KcApp.tsx index 6fe86fa2..b84d534c 100644 --- a/src/lib/components/KcApp.tsx +++ b/src/lib/components/KcApp.tsx @@ -9,6 +9,7 @@ import { Error } from "./Error"; import { LoginResetPassword } from "./LoginResetPassword"; import { LoginVerifyEmail } from "./LoginVerifyEmail"; import { Terms } from "./Terms"; +import { LoginOtp } from "./LoginOtp"; export const KcApp = memo(({ kcContext, ...props }: { kcContext: KcContext; } & KcProps ) => { switch (kcContext.pageId) { @@ -19,5 +20,6 @@ export const KcApp = memo(({ kcContext, ...props }: { kcContext: KcContext; } & case "login-reset-password.ftl": return ; case "login-verify-email.ftl": return ; case "terms.ftl": return ; + case "login-otp.ftl": return ; } }); \ No newline at end of file diff --git a/src/lib/components/LoginOtp.tsx b/src/lib/components/LoginOtp.tsx new file mode 100644 index 00000000..e3612293 --- /dev/null +++ b/src/lib/components/LoginOtp.tsx @@ -0,0 +1,145 @@ + + +import { useEffect, memo } from "react"; +import { Template } from "./Template"; +import type { KcProps } from "./KcProps"; +import type { KcContext } from "../KcContext"; +import { useKcMessage } from "../i18n/useKcMessage"; +import { appendHead } from "../tools/appendHead"; +import { join as pathJoin } from "path"; +import { cx } from "tss-react"; + +export const LoginOtp = memo(({ kcContext, ...props }: { kcContext: KcContext.LoginOtp; } & KcProps) => { + + const { otpLogin, url } = kcContext; + + const { msg, msgStr } = useKcMessage(); + + useEffect( + () => { + + let isCleanedUp = false; + + appendHead({ + "type": "javascript", + "src": pathJoin( + kcContext.url.resourcesCommonPath, + "node_modules/jquery/dist/jquery.min.js" + ) + }).then(() => { + + if (isCleanedUp) return; + + evaluateInlineScript(); + + }); + + return () => { isCleanedUp = true }; + + }, + [] + ); + + return ( +