From 1d8b0a264ea5487581489b92710156b3db16b855 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ng=E1=BB=8Dc=20Long?= Date: Fri, 6 Jan 2023 17:51:43 +0700 Subject: [PATCH] feat(login): add code login limit (#1442) --- controllers/auth.go | 20 ++++++++++---------- i18n/locales/de/data.json | 6 +++--- i18n/locales/en/data.json | 6 +++--- i18n/locales/es/data.json | 6 +++--- i18n/locales/fr/data.json | 6 +++--- i18n/locales/ja/data.json | 6 +++--- i18n/locales/ko/data.json | 6 +++--- i18n/locales/ru/data.json | 6 +++--- i18n/locales/zh/data.json | 6 +++--- object/check.go | 2 +- object/check_util.go | 4 ++-- object/verification.go | 24 +++++++++++++++++++++++- 12 files changed, 60 insertions(+), 38 deletions(-) diff --git a/controllers/auth.go b/controllers/auth.go index 4a44917e..e22f63b1 100644 --- a/controllers/auth.go +++ b/controllers/auth.go @@ -226,12 +226,13 @@ func (c *ApiController) Login() { } // check result through Email or Phone + var checkDest string 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, c.GetAcceptLanguage()) + checkDest = form.Username } else { verificationCodeType = "phone" if len(form.PhonePrefix) == 0 { @@ -242,11 +243,16 @@ func (c *ApiController) Login() { 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, c.GetAcceptLanguage()) + checkDest = fmt.Sprintf("+%s%s", form.PhonePrefix, form.Username) } + user = object.GetUserByFields(form.Organization, form.Username) + if user == nil { + c.ResponseError(fmt.Sprintf(c.T("auth:The user: %s/%s doesn't exist"), form.Organization, form.Username)) + return + } + checkResult = object.CheckSigninCode(user, checkDest, form.Code, c.GetAcceptLanguage()) if len(checkResult) != 0 { - responseText := fmt.Sprintf("%s%s", verificationCodeType, checkResult) + responseText := fmt.Sprintf("%s - %s", verificationCodeType, checkResult) c.ResponseError(responseText) return } @@ -257,12 +263,6 @@ func (c *ApiController) Login() { } else { object.DisableVerificationCode(fmt.Sprintf("+%s%s", form.PhonePrefix, form.Username)) } - - user = object.GetUserByFields(form.Organization, form.Username) - if user == nil { - c.ResponseError(fmt.Sprintf(c.T("auth:The user: %s/%s doesn't exist"), form.Organization, form.Username)) - return - } } else { application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application)) if application == nil { diff --git a/i18n/locales/de/data.json b/i18n/locales/de/data.json index 818725b1..8f8376cb 100644 --- a/i18n/locales/de/data.json +++ b/i18n/locales/de/data.json @@ -67,12 +67,12 @@ "Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).", "Username must have at least 2 characters": "Username must have at least 2 characters", "You don't have the permission to do this": "You don't have the permission to do this", - "You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again": "You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again", + "You have entered the wrong password or code too many times, please wait for %d minutes %d seconds and try again": "You have entered the wrong password or code too many times, please wait for %d minutes %d seconds and try again", "unsupported password type: %s": "unsupported password type: %s" }, "check_util": { - "You have entered the wrong password too many times, please wait for %d minutes and try again": "You have entered the wrong password too many times, please wait for %d minutes and try again", - "password is incorrect, you have %d remaining chances": "password is incorrect, you have %d remaining chances" + "You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again", + "password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances" }, "enforcer": { "Please sign in first": "Please sign in first" diff --git a/i18n/locales/en/data.json b/i18n/locales/en/data.json index 818725b1..8f8376cb 100644 --- a/i18n/locales/en/data.json +++ b/i18n/locales/en/data.json @@ -67,12 +67,12 @@ "Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).", "Username must have at least 2 characters": "Username must have at least 2 characters", "You don't have the permission to do this": "You don't have the permission to do this", - "You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again": "You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again", + "You have entered the wrong password or code too many times, please wait for %d minutes %d seconds and try again": "You have entered the wrong password or code too many times, please wait for %d minutes %d seconds and try again", "unsupported password type: %s": "unsupported password type: %s" }, "check_util": { - "You have entered the wrong password too many times, please wait for %d minutes and try again": "You have entered the wrong password too many times, please wait for %d minutes and try again", - "password is incorrect, you have %d remaining chances": "password is incorrect, you have %d remaining chances" + "You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again", + "password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances" }, "enforcer": { "Please sign in first": "Please sign in first" diff --git a/i18n/locales/es/data.json b/i18n/locales/es/data.json index 818725b1..8f8376cb 100644 --- a/i18n/locales/es/data.json +++ b/i18n/locales/es/data.json @@ -67,12 +67,12 @@ "Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).", "Username must have at least 2 characters": "Username must have at least 2 characters", "You don't have the permission to do this": "You don't have the permission to do this", - "You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again": "You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again", + "You have entered the wrong password or code too many times, please wait for %d minutes %d seconds and try again": "You have entered the wrong password or code too many times, please wait for %d minutes %d seconds and try again", "unsupported password type: %s": "unsupported password type: %s" }, "check_util": { - "You have entered the wrong password too many times, please wait for %d minutes and try again": "You have entered the wrong password too many times, please wait for %d minutes and try again", - "password is incorrect, you have %d remaining chances": "password is incorrect, you have %d remaining chances" + "You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again", + "password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances" }, "enforcer": { "Please sign in first": "Please sign in first" diff --git a/i18n/locales/fr/data.json b/i18n/locales/fr/data.json index 818725b1..8f8376cb 100644 --- a/i18n/locales/fr/data.json +++ b/i18n/locales/fr/data.json @@ -67,12 +67,12 @@ "Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).", "Username must have at least 2 characters": "Username must have at least 2 characters", "You don't have the permission to do this": "You don't have the permission to do this", - "You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again": "You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again", + "You have entered the wrong password or code too many times, please wait for %d minutes %d seconds and try again": "You have entered the wrong password or code too many times, please wait for %d minutes %d seconds and try again", "unsupported password type: %s": "unsupported password type: %s" }, "check_util": { - "You have entered the wrong password too many times, please wait for %d minutes and try again": "You have entered the wrong password too many times, please wait for %d minutes and try again", - "password is incorrect, you have %d remaining chances": "password is incorrect, you have %d remaining chances" + "You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again", + "password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances" }, "enforcer": { "Please sign in first": "Please sign in first" diff --git a/i18n/locales/ja/data.json b/i18n/locales/ja/data.json index 818725b1..8f8376cb 100644 --- a/i18n/locales/ja/data.json +++ b/i18n/locales/ja/data.json @@ -67,12 +67,12 @@ "Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).", "Username must have at least 2 characters": "Username must have at least 2 characters", "You don't have the permission to do this": "You don't have the permission to do this", - "You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again": "You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again", + "You have entered the wrong password or code too many times, please wait for %d minutes %d seconds and try again": "You have entered the wrong password or code too many times, please wait for %d minutes %d seconds and try again", "unsupported password type: %s": "unsupported password type: %s" }, "check_util": { - "You have entered the wrong password too many times, please wait for %d minutes and try again": "You have entered the wrong password too many times, please wait for %d minutes and try again", - "password is incorrect, you have %d remaining chances": "password is incorrect, you have %d remaining chances" + "You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again", + "password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances" }, "enforcer": { "Please sign in first": "Please sign in first" diff --git a/i18n/locales/ko/data.json b/i18n/locales/ko/data.json index 818725b1..8f8376cb 100644 --- a/i18n/locales/ko/data.json +++ b/i18n/locales/ko/data.json @@ -67,12 +67,12 @@ "Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).", "Username must have at least 2 characters": "Username must have at least 2 characters", "You don't have the permission to do this": "You don't have the permission to do this", - "You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again": "You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again", + "You have entered the wrong password or code too many times, please wait for %d minutes %d seconds and try again": "You have entered the wrong password or code too many times, please wait for %d minutes %d seconds and try again", "unsupported password type: %s": "unsupported password type: %s" }, "check_util": { - "You have entered the wrong password too many times, please wait for %d minutes and try again": "You have entered the wrong password too many times, please wait for %d minutes and try again", - "password is incorrect, you have %d remaining chances": "password is incorrect, you have %d remaining chances" + "You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again", + "password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances" }, "enforcer": { "Please sign in first": "Please sign in first" diff --git a/i18n/locales/ru/data.json b/i18n/locales/ru/data.json index 818725b1..8f8376cb 100644 --- a/i18n/locales/ru/data.json +++ b/i18n/locales/ru/data.json @@ -67,12 +67,12 @@ "Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).", "Username must have at least 2 characters": "Username must have at least 2 characters", "You don't have the permission to do this": "You don't have the permission to do this", - "You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again": "You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again", + "You have entered the wrong password or code too many times, please wait for %d minutes %d seconds and try again": "You have entered the wrong password or code too many times, please wait for %d minutes %d seconds and try again", "unsupported password type: %s": "unsupported password type: %s" }, "check_util": { - "You have entered the wrong password too many times, please wait for %d minutes and try again": "You have entered the wrong password too many times, please wait for %d minutes and try again", - "password is incorrect, you have %d remaining chances": "password is incorrect, you have %d remaining chances" + "You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again", + "password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances" }, "enforcer": { "Please sign in first": "Please sign in first" diff --git a/i18n/locales/zh/data.json b/i18n/locales/zh/data.json index 3711ab2c..c71167e1 100644 --- a/i18n/locales/zh/data.json +++ b/i18n/locales/zh/data.json @@ -67,12 +67,12 @@ "Username is too long (maximum is 39 characters).": "用户名过长(最大长度为39个字符)", "Username must have at least 2 characters": "用户名至少要有2个字符", "You don't have the permission to do this": "用户名至少要有2个字符", - "You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again": "输入密码错误次数已达上限,请在 %d 分 %d 秒后重试", + "You have entered the wrong password or code too many times, please wait for %d minutes %d seconds and try again": "You have entered the wrong password or code too many times, please wait for %d minutes %d seconds and try again", "unsupported password type: %s": "不支持的密码类型: %s" }, "check_util": { - "You have entered the wrong password too many times, please wait for %d minutes and try again": "输入密码错误次数已达上限,请在 %d 分后重试", - "password is incorrect, you have %d remaining chances": "密码错误,您还有 %d 次尝试的机会" + "You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again", + "password or code is incorrect, you have %d remaining chances": "密码错误,您还有 %d 次尝试的机会" }, "enforcer": { "Please sign in first": "请先登录" diff --git a/object/check.go b/object/check.go index 3f82c5c9..8e500c75 100644 --- a/object/check.go +++ b/object/check.go @@ -147,7 +147,7 @@ func checkSigninErrorTimes(user *User, lang string) string { // deny the login if the error times is greater than the limit and the last login time is less than the duration if seconds > 0 { - return fmt.Sprintf(i18n.Translate(lang, "check:You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again"), seconds/60, seconds%60) + return fmt.Sprintf(i18n.Translate(lang, "check:You have entered the wrong password or code too many times, please wait for %d minutes %d seconds and try again"), seconds/60, seconds%60) } // reset the error times diff --git a/object/check_util.go b/object/check_util.go index 2017099c..4c9e40cc 100644 --- a/object/check_util.go +++ b/object/check_util.go @@ -58,9 +58,9 @@ func recordSigninErrorInfo(user *User, lang string) string { UpdateUser(user.GetId(), user, []string{"signin_wrong_times", "last_signin_wrong_time"}, user.IsGlobalAdmin) leftChances := SigninWrongTimesLimit - user.SigninWrongTimes if leftChances > 0 { - return fmt.Sprintf(i18n.Translate(lang, "check_util:password is incorrect, you have %d remaining chances"), leftChances) + return fmt.Sprintf(i18n.Translate(lang, "check_util:password or code is incorrect, you have %d remaining chances"), leftChances) } // don't show the chance error message if the user has no chance left - return fmt.Sprintf(i18n.Translate(lang, "check_util:You have entered the wrong password too many times, please wait for %d minutes and try again"), int(LastSignWrongTimeDuration.Minutes())) + return fmt.Sprintf(i18n.Translate(lang, "check_util:You have entered the wrong password or code too many times, please wait for %d minutes and try again"), int(LastSignWrongTimeDuration.Minutes())) } diff --git a/object/verification.go b/object/verification.go index 2f8f8396..5878a00a 100644 --- a/object/verification.go +++ b/object/verification.go @@ -26,6 +26,10 @@ import ( "xorm.io/core" ) +const ( + wrongCode = "wrongCode" +) + type VerificationRecord struct { Owner string `xorm:"varchar(100) notnull pk" json:"owner"` Name string `xorm:"varchar(100) notnull pk" json:"name"` @@ -167,7 +171,7 @@ func CheckVerificationCode(dest, code, lang string) string { } if record.Code != code { - return "Wrong code!" + return wrongCode } return "" @@ -186,6 +190,24 @@ func DisableVerificationCode(dest string) { } } +func CheckSigninCode(user *User, dest, code, lang string) string { + // check the login error times + if msg := checkSigninErrorTimes(user, lang); msg != "" { + return msg + } + + result := CheckVerificationCode(dest, code, lang) + switch result { + case "": + resetUserSigninErrorTimes(user) + return "" + case wrongCode: + return recordSigninErrorInfo(user, lang) + default: + return result + } +} + // From Casnode/object/validateCode.go line 116 var stdNums = []byte("0123456789")