diff --git a/controllers/auth.go b/controllers/auth.go index 05d34a6f..0481340c 100644 --- a/controllers/auth.go +++ b/controllers/auth.go @@ -167,9 +167,16 @@ func (c *ApiController) Login() { var verificationCodeType string var checkResult string + if form.Name != "" { + user = object.GetUserByFields(form.Organization, form.Name) + } + // check result through Email or Phone if strings.Contains(form.Username, "@") { verificationCodeType = "email" + if user != nil && util.GetMaskedEmail(user.Email) == form.Username { + form.Username = user.Email + } checkResult = object.CheckVerificationCode(form.Username, form.Code) } else { verificationCodeType = "phone" @@ -178,6 +185,9 @@ func (c *ApiController) Login() { c.ResponseError(responseText) return } + if user != nil && util.GetMaskedPhone(user.Phone) == form.Username { + form.Username = user.Phone + } checkPhone := fmt.Sprintf("+%s%s", form.PhonePrefix, form.Username) checkResult = object.CheckVerificationCode(checkPhone, form.Code) } diff --git a/controllers/user.go b/controllers/user.go index f7a84841..d9700194 100644 --- a/controllers/user.go +++ b/controllers/user.go @@ -194,15 +194,19 @@ func (c *ApiController) GetEmailAndPhone() { return } - respUser := object.User{Email: user.Email, Phone: user.Phone, Name: user.Name} + respUser := object.User{Name: user.Name} var contentType string switch form.Username { case user.Email: contentType = "email" + respUser.Email = user.Email case user.Phone: contentType = "phone" + respUser.Phone = user.Phone case user.Name: contentType = "username" + respUser.Email = util.GetMaskedEmail(user.Email) + respUser.Phone = util.GetMaskedPhone(user.Phone) } c.ResponseOk(respUser, contentType) diff --git a/controllers/verification.go b/controllers/verification.go index 18969d46..d46e9fc9 100644 --- a/controllers/verification.go +++ b/controllers/verification.go @@ -74,8 +74,16 @@ func (c *ApiController) SendVerificationCode() { } sendResp := errors.New("Invalid dest type") + + if user == nil && checkUser != "" && checkUser != "true" { + _, name := util.GetOwnerAndNameFromId(orgId) + user = object.GetUser(fmt.Sprintf("%s/%s", name, checkUser)) + } switch destType { case "email": + if user != nil && util.GetMaskedEmail(user.Email) == dest { + dest = user.Email + } if !util.IsEmailValid(dest) { c.ResponseError("Invalid Email address") return @@ -84,6 +92,9 @@ func (c *ApiController) SendVerificationCode() { provider := application.GetEmailProvider() sendResp = object.SendVerificationCodeToEmail(organization, user, provider, remoteAddr, dest) case "phone": + if user != nil && util.GetMaskedPhone(user.Phone) == dest { + dest = user.Phone + } if !util.IsPhoneCnValid(dest) { c.ResponseError("Invalid phone number") return diff --git a/util/regex.go b/util/regex.go index a2293183..54898ce5 100644 --- a/util/regex.go +++ b/util/regex.go @@ -20,10 +20,12 @@ import ( ) var rePhoneCn *regexp.Regexp +var rePhone *regexp.Regexp func init() { // https://learnku.com/articles/31543 rePhoneCn, _ = regexp.Compile(`^1(3\d|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8\d|9[0-35-9])\d{8}$`) + rePhone, _ = regexp.Compile("(\\d{3})\\d*(\\d{4})") } func IsEmailValid(email string) bool { @@ -34,3 +36,7 @@ func IsEmailValid(email string) bool { func IsPhoneCnValid(phone string) bool { return rePhoneCn.MatchString(phone) } + +func getMaskedPhone(phone string) string { + return rePhone.ReplaceAllString(phone, "$1****$2") +} \ No newline at end of file diff --git a/util/string.go b/util/string.go index 281470c2..72d20e85 100644 --- a/util/string.go +++ b/util/string.go @@ -206,3 +206,28 @@ func IsChinese(str string) bool { } return flag } + +func GetMaskedPhone(phone string) string { + return getMaskedPhone(phone) +} + +func GetMaskedEmail(email string) string { + if email == "" { + return "" + } + + tokens := strings.Split(email, "@") + username := maskString(tokens[0]) + domain := tokens[1] + domainTokens := strings.Split(domain, ".") + domainTokens[len(domainTokens) - 2] = maskString(domainTokens[len(domainTokens) - 2]) + return fmt.Sprintf("%s@%s", username, strings.Join(domainTokens, ".")) +} + +func maskString(str string) string { + if len(str) <= 2 { + return str + } else { + return fmt.Sprintf("%c%s%c", str[0], strings.Repeat("*", len(str) - 2), str[len(str) - 1]) + } +} \ No newline at end of file diff --git a/web/src/auth/ForgetPage.js b/web/src/auth/ForgetPage.js index b4e569fc..1c22e72f 100644 --- a/web/src/auth/ForgetPage.js +++ b/web/src/auth/ForgetPage.js @@ -13,7 +13,7 @@ // limitations under the License. import React from "react"; -import {Button, Col, Form, Select, Input, Row, Steps} from "antd"; +import {Button, Col, Form, Input, Row, Select, Steps} from "antd"; import * as AuthBackend from "./AuthBackend"; import * as ApplicationBackend from "../backend/ApplicationBackend"; import * as Util from "./Util"; @@ -43,6 +43,7 @@ class ForgetPage extends React.Component { msg: null, userId: "", username: "", + name: "", email: "", isFixed: false, fixedContent: "", @@ -100,7 +101,7 @@ class ForgetPage extends React.Component { if (res.status === "ok") { const phone = res.data.phone; const email = res.data.email; - this.setState({phone: phone, email: email, username: res.data.name}); + this.setState({phone: phone, email: email, username: res.data.name, name: res.data.name}); if (phone !== "" && email === "") { this.setState({ @@ -134,15 +135,16 @@ class ForgetPage extends React.Component { break; case "step2": const oAuthParams = Util.getOAuthGetParameters(); - if(this.state.verifyType=="email"){ + if (this.state.verifyType === "email") { this.setState({username: this.state.email}) - }else if(this.state.verifyType=="phone"){ + } else if (this.state.verifyType === "phone") { this.setState({username: this.state.phone}) } AuthBackend.login({ application: forms.step2.getFieldValue("application"), organization: forms.step2.getFieldValue("organization"), username: this.state.username, + name: this.state.name, code: forms.step2.getFieldValue("emailCode"), phonePrefix: this.state.application?.organizationObj.phonePrefix, type: "login" @@ -179,7 +181,7 @@ class ForgetPage extends React.Component { if (this.state.phone !== "") { options.push( ); } @@ -187,7 +189,7 @@ class ForgetPage extends React.Component { if (this.state.email !== "") { options.push( ); } @@ -349,12 +351,12 @@ class ForgetPage extends React.Component { {this.state.verifyType === "email" ? ( ) : ( )} diff --git a/web/src/common/CountDownInput.js b/web/src/common/CountDownInput.js index ab6e6db7..68844998 100644 --- a/web/src/common/CountDownInput.js +++ b/web/src/common/CountDownInput.js @@ -49,14 +49,6 @@ export const CountDownInput = (props) => { const handleOk = () => { setVisible(false); - if (isValidEmail(onButtonClickArgs[0])) { - onButtonClickArgs[1] = "email"; - } else if (isValidPhone(onButtonClickArgs[0])) { - onButtonClickArgs[1] = "phone"; - } else { - Util.showMessage("error", i18next.t("login:Invalid Email or phone")) - return; - } setButtonLoading(true) UserBackend.sendCode(checkType, checkId, key, ...onButtonClickArgs).then(res => { setKey("");