diff --git a/base-dev/login/messages/messages_zh_Hans.properties b/base-dev/login/messages/messages_zh_Hans.properties index b47ca87..e3ecb17 100644 --- a/base-dev/login/messages/messages_zh_Hans.properties +++ b/base-dev/login/messages/messages_zh_Hans.properties @@ -216,7 +216,7 @@ requiredFields=必填字段 invalidUserMessage=无效的用户名或密码。 invalidUsernameMessage=无效的用户名。 invalidUsernameOrEmailMessage=无效的用户名或电子邮箱。 -invalidPasswordMessage=无效的密码. +invalidPasskeysswordMessage=无效的密码. invalidEmailMessage=无效的电子邮件地址 accountDisabledMessage=账户已被禁用,请联系您的管理员。 accountTemporarilyDisabledMessage=无效的用户名或密码。 diff --git a/keycloak.v2-dev/login/login-phone-or-password.ftl b/keycloak.v2-dev/login/login-phone-or-password.ftl index 5d16505..25b6744 100755 --- a/keycloak.v2-dev/login/login-phone-or-password.ftl +++ b/keycloak.v2-dev/login/login-phone-or-password.ftl @@ -13,6 +13,7 @@ // Add styles loadCSS('${url.resourcesPath}/css/loginPhoneOrPassword.css'); loadCSS('${url.resourcesPath}/css/lib/choices.css'); + loadCSS('${url.resourcesPath}/css/component/smsSenderForm.css');
@@ -41,9 +42,9 @@ <@field.group name="phoneNumber" label=msg("phoneNumber") error="" required=false>
-
+
@@ -91,18 +92,22 @@ diff --git a/keycloak.v2-dev/login/messages/messages_en.properties b/keycloak.v2-dev/login/messages/messages_en.properties new file mode 100644 index 0000000..8d2f10d --- /dev/null +++ b/keycloak.v2-dev/login/messages/messages_en.properties @@ -0,0 +1,49 @@ +# Geetest Captcha +geetestCaptchaLangCode=en + +# Phone number login +phoneNumber=Phone Number +phoneNumberVerified=Phone Number Verified +loginByUsername=Login with Username +loginByPhone=Login with SMS Code +registerByEmail=Register with Email +registerByPhone=Register with SMS Code +resetPasswordByEmail=Email Verification +resetPasswordByPhone=SMS Verification +smsVerificationCode=SMS Verification Code +phoneAreaCountryNameLangCode=en +sendSmsBtn=Send +resendSmsBtn=Resend Verification Code +sendSmsError=Error +captchaLoadError=Failed to load captcha, please refresh and try again +captchaCodeApiError=Failed to get captcha parameters, please refresh and try again +smsSending=Sending... +second=seconds +errorPhoneNumberIsEmpty=Please enter your phone number +errorSendSmsCodeInternalError=Unable to send SMS verification code, please contact the website administrator +errorPhoneAreaNotSupported=This area code is not currently supported, please use email registration instead +errorCaptchaRequired=Please complete the human verification +errorCannotGetConfig=Unable to get verification code configuration, please refresh and try again +errorUserNotFound=No user found for this phone number +errorSendVerificationError=Error sending SMS verification code: {0} + +geetestCaptchaLangCode=en + +# IDP Remember Password +loginSuccessTitle=Login Successful +shouldRememberMe=Keep me logged in on this device? +shouldRememberMeWarning=Do not stay logged in on public computers + +# Custom Properties +nickName=Nickname +optional=Optional + +# Tips +usernameWillPublicWarning=Your username will be displayed publicly, please protect your privacy + +# Logout +frontchannel-logout.title=Logout +frontchannel-logout.message=You are logging out of the following applications +logoutConfirmTitle=Logout +logoutConfirmHeader=Are you sure you want to logout? +doLogout=Logout diff --git a/keycloak.v2-dev/login/messages/messages_zh_Hans.properties b/keycloak.v2-dev/login/messages/messages_zh_Hans.properties new file mode 100644 index 0000000..6c70f7a --- /dev/null +++ b/keycloak.v2-dev/login/messages/messages_zh_Hans.properties @@ -0,0 +1,47 @@ +# 极验 +geetestCaptchaLangCode=zh-cn + +# 手机号登录新增 +phoneNumber=手机号 +phoneNumberVerified=手机号已验证 +loginByUsername=账号密码登录 +loginByPhone=短信验证码登录 +registerByEmail=电子邮箱注册 +registerByPhone=短信验证码注册 +resetPasswordByEmail=电子邮箱验证 +resetPasswordByPhone=短信验证 +smsVerificationCode=短信验证码 +phoneAreaCountryNameLangCode=zh-cn +sendSmsBtn=发送 +resendSmsBtn=重新发送验证码 +sendSmsError=错误 +captchaLoadError=验证码加载失败,请刷新页面重试 +captchaCodeApiError=获取验证码参数失败,请刷新页面重试 +smsSending=发送中... +second=秒 +errorPhoneNumberIsEmpty=请输入手机号 +errorSendSmsCodeInternalError=无法发送短信验证码,请联系网站管理员 +errorPhoneAreaNotSupported=该地区号码暂不支持,请使用邮箱注册 +errorCaptchaRequired=请通过人机验证 +errorCannotGetConfig=无法获取验证码配置,请刷新页面重试 +errorUserNotFound=没有找到该手机号对应的用户 +errorSendVerificationError=发送短信验证码出错: {0} + +# IDP记住密码 +loginSuccessTitle=登录成功 +shouldRememberMe=是否在此设备上保持登录状态? +shouldRememberMeWarning=请勿在公用电脑上保持登录状态 + +# 自定义属性 +nickName=昵称 +optional=可选 + +# 提示 +usernameWillPublicWarning=用户名将会公开显示,请注意保护您的隐私 + +# 登出 +frontchannel-logout.title=登出 +frontchannel-logout.message=您正在登出以下应用 +logoutConfirmTitle=登出 +logoutConfirmHeader=你确定要登出吗? +doLogout=登出 diff --git a/keycloak.v2-dev/login/resources/css/component/smsSenderForm.css b/keycloak.v2-dev/login/resources/css/component/smsSenderForm.css new file mode 100644 index 0000000..8cf8c14 --- /dev/null +++ b/keycloak.v2-dev/login/resources/css/component/smsSenderForm.css @@ -0,0 +1,43 @@ +.areaCodeInputContainer .choices { + width: 4.5em; + text-overflow: clip; + grid-column: 1 / -1; + grid-row: 1 / 2; +} + +.areaCodeInputContainer .choices[data-type*=select-one]::after { + border-color: var(--pf-v5-global--Color--100) transparent transparent transparent !important; +} + +.areaCodeInputContainer .choices .choices__inner { + background-color: transparent; + border: none; + border-radius: 0; +} + +.areaCodeInputContainer .choices__list--dropdown, .choices__list[aria-expanded] { + margin-top: 0 !important; + color: var(--pf-v5-global--Color--100) !important; + + --pf-v5-c-menu--BackgroundColor: var(--pf-v5-global--BackgroundColor--100); + --pf-v5-c-menu--BoxShadow: var(--pf-v5-global--BoxShadow--md); + --pf-v5-c-menu__list-item--hover--BackgroundColor: var(--pf-v5-global--BackgroundColor--200); + + background-color: var(--pf-v5-c-menu--BackgroundColor) !important; + border: none !important; + box-shadow: var(--pf-v5-c-menu--BoxShadow) !important; +} + +.areaCodeInputContainer .choices__list--dropdown .choices__item--selectable.is-highlighted, +.choices__list[aria-expanded] .choices__item--selectable.is-highlighted { + background-color: var(--pf-v5-c-menu__list-item--hover--BackgroundColor) !important; +} + +.areaCodeInputContainer .choices__input { + color: var(--pf-v5-global--Color--100) !important; + background-color: transparent !important; +} + +.areaCodeInputContainer .choices[data-type*="select-one"] .choices__input { + border-color: var(--pf-v5-global--BorderColor--200) !important; +} \ No newline at end of file diff --git a/keycloak.v2-dev/login/resources/css/lib/choices.css b/keycloak.v2-dev/login/resources/css/lib/choices.css index 07cfd48..3149a6d 100644 --- a/keycloak.v2-dev/login/resources/css/lib/choices.css +++ b/keycloak.v2-dev/login/resources/css/lib/choices.css @@ -33,9 +33,6 @@ .choices[data-type*=select-one] { cursor: pointer; } -.choices[data-type*=select-one] .choices__inner { - padding-bottom: 7.5px; -} .choices[data-type*=select-one] .choices__input { display: block; width: 100%; @@ -82,7 +79,6 @@ } .choices[data-type*=select-one].is-open::after { border-color: transparent transparent #333; - margin-top: -7.5px; } .choices[data-type*=select-one][dir=rtl]::after { left: 11.5px; @@ -123,15 +119,15 @@ } .choices__inner { - display: inline-block; - vertical-align: top; + display: flex; + align-items: center; width: 100%; background-color: #f9f9f9; - padding: 7.5px 7.5px 3.75px; border: 1px solid #ddd; border-radius: 2.5px; font-size: 14px; - min-height: 44px; + min-height: 24px; + height: 100%; overflow: hidden; } .is-focused .choices__inner, .is-open .choices__inner { @@ -146,12 +142,12 @@ .choices__list { margin: 0; - padding-left: 0; + padding-inline-start: 8px; list-style: none; } .choices__list--single { display: inline-block; - padding: 4px 16px 4px 4px; + padding: 8px 16px 8px 8px; width: 100%; } [dir=rtl] .choices__list--single { @@ -206,6 +202,7 @@ border: 1px solid #ddd; top: 100%; margin-top: -1px; + padding-left: 0; border-bottom-left-radius: 2.5px; border-bottom-right-radius: 2.5px; overflow: hidden; diff --git a/keycloak.v2-dev/login/resources/css/loginPhoneOrPassword.css b/keycloak.v2-dev/login/resources/css/loginPhoneOrPassword.css index 6639c96..1a2338b 100644 --- a/keycloak.v2-dev/login/resources/css/loginPhoneOrPassword.css +++ b/keycloak.v2-dev/login/resources/css/loginPhoneOrPassword.css @@ -7,40 +7,22 @@ html, body { height: auto !important; } -#kc-info-wrapper > div, -#kc-info-wrapper > div > div { - display: inline-block; -} - -.login-pf-page .login-pf-header h1 { - margin-top: 10px; - font-size: 2em; - font-weight: bold; -} - -@media (max-width: 767px) { - #kc-info { - margin: 20px 0 0 0; - } -} - -@media (min-width: 768px) { - .login-pf-page { - padding-bottom: 5em; - } -} - #kc-locale ul { max-height: 200px; max-height: 50vh; overflow-y: auto; } -#kc-register-form .tab-content { - margin-bottom: 15px; +.pf-v5-c-form { + --pf-v5-c-form--GridGap: 1rem; } -#areaCodeInput { - width: 5.5em; - text-overflow: clip; +.pf-v5-c-tab-content { + display: flex; + flex-direction: column; + gap: var(--pf-v5-c-form--GridGap); } + +.pf-v5-c-tab-content[hidden] { + display: none; +} \ No newline at end of file diff --git a/keycloak.v2-dev/login/resources/js/component/smsSenderForm.js b/keycloak.v2-dev/login/resources/js/component/smsSenderForm.js index 5e4ed59..0d9a445 100644 --- a/keycloak.v2-dev/login/resources/js/component/smsSenderForm.js +++ b/keycloak.v2-dev/login/resources/js/component/smsSenderForm.js @@ -56,12 +56,24 @@ export class SmsSenderForm { }); this.$form.addEventListener("submit", () => { - if (this.areaCodeSelect) { - this.areaCodeSelect.enable(); + if (this.countdown !== null) { + this.stopCountdown(); } + + this.enableAll(); + + return true; }); } + enableAll() { + this.$inputPhoneNumber.disabled = false; + this.$btnSend.disabled = false; + if (this.areaCodeSelect) { + this.areaCodeSelect.enable(); + } + } + initCaptcha() { this.captcha = new PhoneProviderGeetestCaptcha(); } @@ -123,7 +135,7 @@ export class SmsSenderForm { }, }; }); - this.areaCodeSelect.setChoices(opts, "value", "label", true); + this.areaCodeSelect.setChoices(opts, "value", "label"); } startCountdown() { @@ -168,7 +180,7 @@ export class SmsSenderForm { this.$btnSend.disabled = true; this.$btnSend.textContent = msg.localize("sending"); - data.areaCode = this.areaCodeSelect.getValue(); + data.areaCode = this.areaCodeSelect.getValue(true); data.phoneNumber = this.$inputPhoneNumber.value; fetch(this.realmUrl + "/sms/" + this.type + "-code", { diff --git a/keycloak.v2-dev/login/resources/js/lib/common.js b/keycloak.v2-dev/login/resources/js/lib/common.js index 46f5fd8..8f95a6f 100644 --- a/keycloak.v2-dev/login/resources/js/lib/common.js +++ b/keycloak.v2-dev/login/resources/js/lib/common.js @@ -19,15 +19,29 @@ class Message { if (this.messages.has(msgId)) { return this.replaceVariables(this.messages.get(msgId) || '{' + msgId + '}', args); } else { + console.warn(`Missing localization for message id: ${msgId}`); return '{' + msgId + '}'; } } + localizeOrNull(msgId, args) { + if (this.messages.has(msgId)) { + return this.replaceVariables(this.messages.get(msgId) || '{' + msgId + '}', args); + } else { + return null; + } + } + + textOrNull(msgId, args) { + return this.localizeOrNull(msgId, args); + } + // Alias for compatibility text(msgId, args) { return this.localize(msgId, args); } + replaceVariables(template, params = []) { let result = template; let paramId; diff --git a/keycloak.v2-dev/login/resources/js/lib/gtutils.js b/keycloak.v2-dev/login/resources/js/lib/gtutils.js index 2635820..a059463 100644 --- a/keycloak.v2-dev/login/resources/js/lib/gtutils.js +++ b/keycloak.v2-dev/login/resources/js/lib/gtutils.js @@ -20,6 +20,7 @@ export class PhoneProviderGeetestCaptcha { offline: !data.success, new_captcha: true, product: 'bind', + lang: msg.textOrNull('geetestCaptchaLangCode') || 'en' }, (obj) => { this._captchaObj = obj; if (this._shouldCallCaptcha) { //加载完成后立刻调用 diff --git a/keycloak.v2-dev/login/theme.properties b/keycloak.v2-dev/login/theme.properties index 1c79112..b638000 100644 --- a/keycloak.v2-dev/login/theme.properties +++ b/keycloak.v2-dev/login/theme.properties @@ -94,7 +94,7 @@ kcLoginMainBody=pf-v5-c-login__main-body kcContentWrapperClass=pf-v5-u-mb-md-on-md kcWebAuthnDefaultIcon=pf-v5-c-icon pf-m-lg -kcMarginTopClass=pf-v5-u-mt-md-on-md +kcMarginTopClass=pf-v5-u-mt-md kcLoginOTPListClass=pf-v5-c-tile kcLoginOTPListItemHeaderClass=pf-v5-c-tile__header pf-m-stacked