diff --git a/assets b/assets index 2d20892..47493d6 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 2d20892994d041953cecaba1ecc2d8be7abd5a4a +Subproject commit 47493d67d7b08192a406f68cf2e9a31a46f37104 diff --git a/middleware/captcha.go b/middleware/captcha.go index cb1f845..baf24a5 100644 --- a/middleware/captcha.go +++ b/middleware/captcha.go @@ -24,6 +24,11 @@ type req struct { Randstr string `json:"randstr"` } +const ( + captchaNotMatch = "CAPTCHA not match." + captchaRefresh = "Verification failed, please refresh the page and retry." +) + // CaptchaRequired 验证请求签名 func CaptchaRequired(configName string) gin.HandlerFunc { return func(c *gin.Context) { @@ -43,7 +48,7 @@ func CaptchaRequired(configName string) gin.HandlerFunc { bodyCopy := new(bytes.Buffer) _, err := io.Copy(bodyCopy, c.Request.Body) if err != nil { - c.JSON(200, serializer.ParamErr("验证码错误", err)) + c.JSON(200, serializer.Err(serializer.CodeCaptchaError, captchaNotMatch, err)) c.Abort() return } @@ -51,7 +56,7 @@ func CaptchaRequired(configName string) gin.HandlerFunc { bodyData := bodyCopy.Bytes() err = json.Unmarshal(bodyData, &service) if err != nil { - c.JSON(200, serializer.ParamErr("验证码错误", err)) + c.JSON(200, serializer.Err(serializer.CodeCaptchaError, captchaNotMatch, err)) c.Abort() return } @@ -62,7 +67,7 @@ func CaptchaRequired(configName string) gin.HandlerFunc { captchaID := util.GetSession(c, "captchaID") util.DeleteSession(c, "captchaID") if captchaID == nil || !base64Captcha.VerifyCaptcha(captchaID.(string), service.CaptchaCode) { - c.JSON(200, serializer.ParamErr("验证码错误", nil)) + c.JSON(200, serializer.Err(serializer.CodeCaptchaError, captchaNotMatch, err)) c.Abort() return } @@ -71,15 +76,15 @@ func CaptchaRequired(configName string) gin.HandlerFunc { case "recaptcha": reCAPTCHA, err := recaptcha.NewReCAPTCHA(options["captcha_ReCaptchaSecret"], recaptcha.V2, 10*time.Second) if err != nil { - util.Log().Warning("reCAPTCHA 验证错误, %s", err) + util.Log().Warning("reCAPTCHA verification failed, %s", err) c.Abort() break } err = reCAPTCHA.Verify(service.CaptchaCode) if err != nil { - util.Log().Warning("reCAPTCHA 验证错误, %s", err) - c.JSON(200, serializer.ParamErr("验证失败,请刷新网页后再次验证", nil)) + util.Log().Warning("reCAPTCHA verification failed, %s", err) + c.JSON(200, serializer.Err(serializer.CodeCaptchaRefreshNeeded, captchaRefresh, nil)) c.Abort() return } @@ -103,13 +108,13 @@ func CaptchaRequired(configName string) gin.HandlerFunc { request.UserIp = common.StringPtr(c.ClientIP()) response, err := client.DescribeCaptchaResult(request) if err != nil { - util.Log().Warning("TCaptcha 验证错误, %s", err) + util.Log().Warning("TCaptcha verification failed, %s", err) c.Abort() break } if *response.Response.CaptchaCode != int64(1) { - c.JSON(200, serializer.ParamErr("验证失败,请刷新网页后再次验证", nil)) + c.JSON(200, serializer.Err(serializer.CodeCaptchaRefreshNeeded, captchaRefresh, nil)) c.Abort() return } diff --git a/middleware/common.go b/middleware/common.go index c3a2283..8acc2c3 100644 --- a/middleware/common.go +++ b/middleware/common.go @@ -30,7 +30,7 @@ func HashID(IDType int) gin.HandlerFunc { func IsFunctionEnabled(key string) gin.HandlerFunc { return func(c *gin.Context) { if !model.IsTrueVal(model.GetSettingByName(key)) { - c.JSON(200, serializer.Err(serializer.CodeNoPermissionErr, "未开启此功能", nil)) + c.JSON(200, serializer.Err(serializer.CodeFeatureNotEnabled, "This feature is not enabled", nil)) c.Abort() return } diff --git a/pkg/serializer/error.go b/pkg/serializer/error.go index 546af1b..d264612 100644 --- a/pkg/serializer/error.go +++ b/pkg/serializer/error.go @@ -98,6 +98,20 @@ const ( Code2FACodeErr = 40022 // CodeLoginSessionNotExist 登录会话不存在 CodeLoginSessionNotExist = 40023 + // CodeInitializeAuthn 无法初始化 WebAuthn + CodeInitializeAuthn = 40024 + // CodeWebAuthnCredentialError WebAuthn 凭证无效 + CodeWebAuthnCredentialError = 40025 + // CodeCaptchaError 验证码错误 + CodeCaptchaError = 40026 + // CodeCaptchaRefreshNeeded 验证码需要刷新 + CodeCaptchaRefreshNeeded = 40027 + // CodeFailedSendEmail 邮件发送失败 + CodeFailedSendEmail = 40028 + // CodeInvalidTempLink 临时链接无效 + CodeInvalidTempLink = 40029 + // CodeTempLinkExpired 临时链接过期 + CodeTempLinkExpired = 40030 // CodeDBError 数据库操作失败 CodeDBError = 50001 // CodeEncryptError 加密失败 diff --git a/routers/controllers/main.go b/routers/controllers/main.go index 3c94d29..aaac8b2 100644 --- a/routers/controllers/main.go +++ b/routers/controllers/main.go @@ -34,7 +34,7 @@ func ParamErrorMsg(filed string, tag string) string { tagVal, findTag := tagMap[tag] if findTag { // 返回拼接出来的错误信息 - return fieldVal + tagVal + return fieldVal + " " + tagVal } return "" } diff --git a/routers/controllers/user.go b/routers/controllers/user.go index 7a10980..a99b6c8 100644 --- a/routers/controllers/user.go +++ b/routers/controllers/user.go @@ -20,13 +20,13 @@ func StartLoginAuthn(c *gin.Context) { userName := c.Param("username") expectedUser, err := model.GetActiveUserByEmail(userName) if err != nil { - c.JSON(200, serializer.Err(serializer.CodeNotFound, "用户不存在", err)) + c.JSON(200, serializer.Err(serializer.CodeUserNotFound, "User not exist", err)) return } instance, err := authn.NewAuthnInstance() if err != nil { - c.JSON(200, serializer.Err(serializer.CodeInternalSetting, "无法初始化Authn", err)) + c.JSON(200, serializer.Err(serializer.CodeInitializeAuthn, "Cannot initialize authn", err)) return } @@ -54,7 +54,7 @@ func FinishLoginAuthn(c *gin.Context) { userName := c.Param("username") expectedUser, err := model.GetActiveUserByEmail(userName) if err != nil { - c.JSON(200, serializer.Err(serializer.CodeCredentialInvalid, "用户邮箱或密码错误", err)) + c.JSON(200, serializer.Err(serializer.CodeUserNotFound, "User not exist", err)) return } @@ -65,14 +65,14 @@ func FinishLoginAuthn(c *gin.Context) { instance, err := authn.NewAuthnInstance() if err != nil { - c.JSON(200, serializer.Err(serializer.CodeInternalSetting, "无法初始化Authn", err)) + c.JSON(200, serializer.Err(serializer.CodeInitializeAuthn, "Cannot initialize authn", err)) return } _, err = instance.FinishLogin(expectedUser, sessionData, c.Request) if err != nil { - c.JSON(200, serializer.Err(serializer.CodeCredentialInvalid, "登录验证失败", err)) + c.JSON(200, serializer.Err(serializer.CodeWebAuthnCredentialError, "Verification failed", err)) return } diff --git a/service/user/login.go b/service/user/login.go index 3e7fa34..9367ae9 100644 --- a/service/user/login.go +++ b/service/user/login.go @@ -37,24 +37,24 @@ func (service *UserResetService) Reset(c *gin.Context) serializer.Response { // 取得原始用户ID uid, err := hashid.DecodeHashID(service.ID, hashid.UserID) if err != nil { - return serializer.Err(serializer.CodeNotFound, "重设链接无效", err) + return serializer.Err(serializer.CodeInvalidTempLink, "Invalid link", err) } // 检查重设会话 resetSession, exist := cache.Get(fmt.Sprintf("user_reset_%d", uid)) if !exist || resetSession.(string) != service.Secret { - return serializer.Err(serializer.CodeNotFound, "链接已过期", err) + return serializer.Err(serializer.CodeTempLinkExpired, "Link is expired", err) } // 重设用户密码 user, err := model.GetActiveUserByID(uid) if err != nil { - return serializer.Err(serializer.CodeNotFound, "用户不存在", err) + return serializer.Err(serializer.CodeUserNotFound, "User not found", nil) } user.SetPassword(service.Password) if err := user.Update(map[string]interface{}{"password": user.Password}); err != nil { - return serializer.DBErr("无法重设密码", err) + return serializer.DBErr("Failed to reset password", err) } cache.Deletes([]string{fmt.Sprintf("%d", uid)}, "user_reset_") @@ -67,10 +67,10 @@ func (service *UserResetEmailService) Reset(c *gin.Context) serializer.Response if user, err := model.GetUserByEmail(service.UserName); err == nil { if user.Status == model.Baned || user.Status == model.OveruseBaned { - return serializer.Err(403, "该账号已被封禁", nil) + return serializer.Err(serializer.CodeUserBaned, "This user is banned", nil) } if user.Status == model.NotActivicated { - return serializer.Err(403, "该账号未激活", nil) + return serializer.Err(serializer.CodeUserNotActivated, "This user is not activated", nil) } // 创建密码重设会话 secret := util.RandStringRunes(32) @@ -87,7 +87,7 @@ func (service *UserResetEmailService) Reset(c *gin.Context) serializer.Response // 发送密码重设邮件 title, body := email.NewResetEmail(user.Nick, finalURL.String()) if err := email.Send(user.Email, title, body); err != nil { - return serializer.Err(serializer.CodeInternalSetting, "无法发送密码重设邮件", err) + return serializer.Err(serializer.CodeFailedSendEmail, "Failed to send email", err) } }