From c091089830efb97f3d8899cc3d982cfe1562e90b Mon Sep 17 00:00:00 2001 From: Joseph Garrone <joseph.garrone.gj@gmail.com> Date: Tue, 6 Feb 2024 07:59:21 +0100 Subject: [PATCH] Apply #502 from main --- src/login/lib/useGetClassName.ts | 2 +- src/login/pages/LoginOtp.tsx | 160 +++++++++++++------------------ 2 files changed, 66 insertions(+), 96 deletions(-) diff --git a/src/login/lib/useGetClassName.ts b/src/login/lib/useGetClassName.ts index 2692cfb5..25bb6572 100644 --- a/src/login/lib/useGetClassName.ts +++ b/src/login/lib/useGetClassName.ts @@ -94,7 +94,7 @@ export const { useGetClassName } = createUseClassName<ClassKey>({ "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 col-xs-12", "kcSelectOTPListItemClass": "card-pf-body card-pf-top-element", "kcAuthenticatorOtpCircleClass": "fa fa-mobile card-pf-icon-circle", "kcSelectOTPItemHeadingClass": "card-pf-title text-center", diff --git a/src/login/pages/LoginOtp.tsx b/src/login/pages/LoginOtp.tsx index f4e99d34..3dc8419b 100644 --- a/src/login/pages/LoginOtp.tsx +++ b/src/login/pages/LoginOtp.tsx @@ -1,5 +1,3 @@ -import { useEffect } from "react"; -import { headInsert } from "keycloakify/tools/headInsert"; import { clsx } from "keycloakify/tools/clsx"; import type { PageProps } from "keycloakify/login/pages/PageProps"; import { useGetClassName } from "keycloakify/login/lib/useGetClassName"; @@ -18,105 +16,77 @@ export default function LoginOtp(props: PageProps<Extract<KcContext, { pageId: " const { msg, msgStr } = i18n; - useEffect(() => { - let isCleanedUp = false; - - const { prLoaded, remove } = headInsert({ - "type": "javascript", - "src": `${kcContext.url.resourcesCommonPath}/node_modules/jquery/dist/jquery.min.js` - }); - - (async () => { - await prLoaded; - - if (isCleanedUp) { - return; - } - - evaluateInlineScript(); - })(); - - return () => { - isCleanedUp = true; - remove(); - }; - }, []); - return ( - <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} headerNode={msg("doLogIn")}> - <form id="kc-otp-login-form" className={getClassName("kcFormClass")} action={url.loginAction} method="post"> - {otpLogin.userOtpCredentials.length > 1 && ( - <div className={getClassName("kcFormGroupClass")}> - <div className={getClassName("kcInputWrapperClass")}> - {otpLogin.userOtpCredentials.map(otpCredential => ( - <div key={otpCredential.id} className={getClassName("kcSelectOTPListClass")}> - <input type="hidden" value="${otpCredential.id}" /> - <div className={getClassName("kcSelectOTPListItemClass")}> - <span className={getClassName("kcAuthenticatorOtpCircleClass")} /> - <h2 className={getClassName("kcSelectOTPItemHeadingClass")}>{otpCredential.userLabel}</h2> + <> + <style> + {` + input[type="radio"]:checked~label.kcSelectOTPListClass{ + border: 2px solid #39a5dc; + }`} + </style> + <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} headerNode={msg("doLogIn")}> + <form id="kc-otp-login-form" className={getClassName("kcFormClass")} action={url.loginAction} method="post"> + {otpLogin.userOtpCredentials.length > 1 && ( + <div className={getClassName("kcFormGroupClass")}> + <div className={getClassName("kcInputWrapperClass")}> + {otpLogin.userOtpCredentials.map((otpCredential, index) => ( + <div key={otpCredential.id}> + <input + id={`kc-otp-credential-${index}`} + name="selectedCredentialId" + type="radio" + value={otpCredential.id} + style={{ display: "none" }} + /> + <label + htmlFor={`kc-otp-credential-${index}`} + key={otpCredential.id} + className={getClassName("kcSelectOTPListClass")} + > + <div className={getClassName("kcSelectOTPListItemClass")}> + <span className={getClassName("kcAuthenticatorOtpCircleClass")} /> + <h2 className={getClassName("kcSelectOTPItemHeadingClass")}>{otpCredential.userLabel}</h2> + </div> + </label> </div> - </div> - ))} + ))} + </div> + </div> + )} + <div className={getClassName("kcFormGroupClass")}> + <div className={getClassName("kcLabelWrapperClass")}> + <label htmlFor="otp" className={getClassName("kcLabelClass")}> + {msg("loginOtpOneTime")} + </label> + </div> + + <div className={getClassName("kcInputWrapperClass")}> + <input id="otp" name="otp" autoComplete="off" type="text" className={getClassName("kcInputClass")} autoFocus /> </div> </div> - )} - <div className={getClassName("kcFormGroupClass")}> - <div className={getClassName("kcLabelWrapperClass")}> - <label htmlFor="otp" className={getClassName("kcLabelClass")}> - {msg("loginOtpOneTime")} - </label> - </div> - <div className={getClassName("kcInputWrapperClass")}> - <input id="otp" name="otp" autoComplete="off" type="text" className={getClassName("kcInputClass")} autoFocus /> - </div> - </div> + <div className={getClassName("kcFormGroupClass")}> + <div id="kc-form-options" className={getClassName("kcFormOptionsClass")}> + <div className={getClassName("kcFormOptionsWrapperClass")} /> + </div> - <div className={getClassName("kcFormGroupClass")}> - <div id="kc-form-options" className={getClassName("kcFormOptionsClass")}> - <div className={getClassName("kcFormOptionsWrapperClass")} /> + <div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}> + <input + className={clsx( + getClassName("kcButtonClass"), + getClassName("kcButtonPrimaryClass"), + getClassName("kcButtonBlockClass"), + getClassName("kcButtonLargeClass") + )} + name="login" + id="kc-login" + type="submit" + value={msgStr("doLogIn")} + /> + </div> </div> - - <div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}> - <input - className={clsx( - getClassName("kcButtonClass"), - getClassName("kcButtonPrimaryClass"), - getClassName("kcButtonBlockClass"), - getClassName("kcButtonLargeClass") - )} - name="login" - id="kc-login" - type="submit" - value={msgStr("doLogIn")} - /> - </div> - </div> - </form> - </Template> + </form> + </Template> + </> ); } - -declare const $: any; - -function evaluateInlineScript() { - $(document).ready(function () { - // Card Single Select - $(".card-pf-view-single-select").click(function (this: any) { - if ($(this).hasClass("active")) { - $(this).removeClass("active"); - $(this).children().removeAttr("name"); - } else { - $(".card-pf-view-single-select").removeClass("active"); - $(".card-pf-view-single-select").children().removeAttr("name"); - $(this).addClass("active"); - $(this).children().attr("name", "selectedCredentialId"); - } - }); - - var defaultCred = $(".card-pf-view-single-select")[0]; - if (defaultCred) { - defaultCred.click(); - } - }); -}