完成手机号登录界面

main
落雨楓 1 week ago
parent 13a775ff45
commit b2f1919c9d

@ -216,7 +216,7 @@ requiredFields=必填字段
invalidUserMessage=无效的用户名或密码。
invalidUsernameMessage=无效的用户名。
invalidUsernameOrEmailMessage=无效的用户名或电子邮箱。
invalidPasswordMessage=无效的密码.
invalidPasskeysswordMessage=无效的密码.
invalidEmailMessage=无效的电子邮件地址
accountDisabledMessage=账户已被禁用,请联系您的管理员。
accountTemporarilyDisabledMessage=无效的用户名或密码。

@ -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');
</script>
<div id="kc-form">
@ -41,9 +42,9 @@
<@field.group name="phoneNumber" label=msg("phoneNumber") error="" required=false>
<div class="${properties.kcInputGroup!}">
<div class="${properties.kcInputGroupItemClass!}">
<div class="${properties.kcInputClass!}">
<div class="${properties.kcInputClass!} areaCodeInputContainer">
<select tabindex="1" class="areaCodeInput" name="areaCode" data-value="${(auth.areaCode!'')}">
<option value="" disabled selected>${msg("loading")}</option>
</select>
</div>
</div>
@ -91,18 +92,22 @@
</script>
<script type="application/json" data-messages>
{
"error": "错误",
"captcha-load-error": "无法加载验证码,请刷新重试",
"captcha-code-api-error": "无法访问Api",
"countryNameLangCode": "zh-cn",
"sending": "正在发送...",
"sendVerificationCode": "发送验证码",
"resendVerificationCode": "重新发送",
"second": "秒",
"phoneNumberIsEmpty": "请填写手机号码",
"cannotGetConfig": "无法读取配置文件",
"sendVerificationError": "发送短信验证码出错: {1}",
"loading": "加载中..."
"geetestCaptchaLangCode": "${msg("geetestCaptchaLangCode")}",
"error": "${msg("sendSmsError")}",
"captchaLoadError": "${msg("captchaLoadError")}",
"captchaCodeApiError": "${msg("captchaCodeApiError")}",
"countryNameLangCode": "${msg("phoneAreaCountryNameLangCode")}",
"sending": "${msg("smsSending")}",
"sendVerificationCode": "${msg("sendSmsBtn")}",
"resendVerificationCode": "${msg("resendSmsBtn")}",
"second": "${msg("second")}",
"phoneNumberIsEmpty": "${msg("errorPhoneNumberIsEmpty")}",
"sendSmsCodeError": "${msg("errorSendSmsCodeInternalError")}",
"areaNotSupported": "${msg("errorPhoneAreaNotSupported")}",
"captchaNotCompleted": "${msg("errorCaptchaRequired")}",
"cannotGetConfig": "${msg("errorCannotGetConfig")}",
"userNotExists": "${msg("errorUserNotFound")}",
"sendVerificationError": "${msg("errorSendVerificationError")}"
}
</script>
<script type="module" src="${url.resourcesPath}/js/loginPhoneOrPassword.js"></script>

@ -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

@ -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=登出

@ -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;
}

@ -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;

@ -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;
}

@ -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", {

@ -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;

@ -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) { //加载完成后立刻调用

@ -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

Loading…
Cancel
Save