From 2f1a01af7fff10eae610ab6d6d8fed656191de3c Mon Sep 17 00:00:00 2001 From: Neo Date: Sat, 16 May 2026 02:33:10 -0700 Subject: [PATCH 1/2] [GPT-5 Codex] fix auth: localize WeChat OAuth - Route current-user WeChat and custom OAuth responses through backend i18n. - Add matching en, zh-CN, and zh-TW messages. - Keep admin custom OAuth management endpoints unchanged. --- controller/custom_oauth.go | 9 +++-- controller/wechat.go | 79 +++++++++++++++----------------------- i18n/keys.go | 7 ++++ i18n/locales/en.yaml | 5 +++ i18n/locales/zh-CN.yaml | 5 +++ i18n/locales/zh-TW.yaml | 5 +++ 6 files changed, 59 insertions(+), 51 deletions(-) diff --git a/controller/custom_oauth.go b/controller/custom_oauth.go index c21ec7910bc..ff293e728a0 100644 --- a/controller/custom_oauth.go +++ b/controller/custom_oauth.go @@ -10,6 +10,7 @@ import ( "time" "github.com/QuantumNous/new-api/common" + "github.com/QuantumNous/new-api/i18n" "github.com/QuantumNous/new-api/model" "github.com/QuantumNous/new-api/oauth" "github.com/gin-gonic/gin" @@ -469,7 +470,7 @@ func buildUserOAuthBindingsResponse(userId int) ([]UserOAuthBindingResponse, err func GetUserOAuthBindings(c *gin.Context) { userId := c.GetInt("id") if userId == 0 { - common.ApiErrorMsg(c, "未登录") + common.ApiErrorI18n(c, i18n.MsgUnauthorized) return } @@ -523,14 +524,14 @@ func GetUserOAuthBindingsByAdmin(c *gin.Context) { func UnbindCustomOAuth(c *gin.Context) { userId := c.GetInt("id") if userId == 0 { - common.ApiErrorMsg(c, "未登录") + common.ApiErrorI18n(c, i18n.MsgUnauthorized) return } providerIdStr := c.Param("provider_id") providerId, err := strconv.Atoi(providerIdStr) if err != nil { - common.ApiErrorMsg(c, "无效的提供商 ID") + common.ApiErrorI18n(c, i18n.MsgInvalidId) return } @@ -541,7 +542,7 @@ func UnbindCustomOAuth(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "success": true, - "message": "解绑成功", + "message": i18n.T(c, i18n.MsgCustomOAuthUnbindSuccess), }) } diff --git a/controller/wechat.go b/controller/wechat.go index 8889daca77d..279eedda8f5 100644 --- a/controller/wechat.go +++ b/controller/wechat.go @@ -10,12 +10,18 @@ import ( "time" "github.com/QuantumNous/new-api/common" + "github.com/QuantumNous/new-api/i18n" "github.com/QuantumNous/new-api/model" "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" ) +var ( + errWeChatInvalidCode = errors.New("wechat code is empty") + errWeChatVerificationFailed = errors.New("wechat verification failed") +) + type wechatLoginResponse struct { Success bool `json:"success"` Message string `json:"message"` @@ -24,7 +30,7 @@ type wechatLoginResponse struct { func getWeChatIdByCode(code string) (string, error) { if code == "" { - return "", errors.New("无效的参数") + return "", errWeChatInvalidCode } req, err := http.NewRequest("GET", fmt.Sprintf("%s/api/wechat/user?code=%s", common.WeChatServerAddress, url.QueryEscape(code)), nil) if err != nil { @@ -45,29 +51,35 @@ func getWeChatIdByCode(code string) (string, error) { return "", err } if !res.Success { - return "", errors.New(res.Message) + return "", errWeChatVerificationFailed } if res.Data == "" { - return "", errors.New("验证码错误或已过期") + return "", errWeChatVerificationFailed } return res.Data, nil } +func apiWeChatError(c *gin.Context, err error) { + switch { + case errors.Is(err, errWeChatInvalidCode): + common.ApiErrorI18n(c, i18n.MsgInvalidParams) + case errors.Is(err, errWeChatVerificationFailed): + common.ApiErrorI18n(c, i18n.MsgUserVerificationCodeError) + default: + common.SysError("wechat auth failed: " + err.Error()) + common.ApiErrorI18n(c, i18n.MsgOAuthConnectFailed, map[string]any{"Provider": "WeChat"}) + } +} + func WeChatAuth(c *gin.Context) { if !common.WeChatAuthEnabled { - c.JSON(http.StatusOK, gin.H{ - "message": "管理员未开启通过微信登录以及注册", - "success": false, - }) + common.ApiErrorI18n(c, i18n.MsgWeChatNotEnabled) return } code := c.Query("code") wechatId, err := getWeChatIdByCode(code) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "message": err.Error(), - "success": false, - }) + apiWeChatError(c, err) return } user := model.User{ @@ -76,17 +88,11 @@ func WeChatAuth(c *gin.Context) { if model.IsWeChatIdAlreadyTaken(wechatId) { err := user.FillUserByWeChatId() if err != nil { - c.JSON(http.StatusOK, gin.H{ - "success": false, - "message": err.Error(), - }) + common.ApiError(c, err) return } if user.Id == 0 { - c.JSON(http.StatusOK, gin.H{ - "success": false, - "message": "用户已注销", - }) + common.ApiErrorI18n(c, i18n.MsgOAuthUserDeleted) return } } else { @@ -97,26 +103,17 @@ func WeChatAuth(c *gin.Context) { user.Status = common.UserStatusEnabled if err := user.Insert(0); err != nil { - c.JSON(http.StatusOK, gin.H{ - "success": false, - "message": err.Error(), - }) + common.ApiError(c, err) return } } else { - c.JSON(http.StatusOK, gin.H{ - "success": false, - "message": "管理员关闭了新用户注册", - }) + common.ApiErrorI18n(c, i18n.MsgUserRegisterDisabled) return } } if user.Status != common.UserStatusEnabled { - c.JSON(http.StatusOK, gin.H{ - "message": "用户已被封禁", - "success": false, - }) + common.ApiErrorI18n(c, i18n.MsgUserDisabled) return } setupLogin(&user, c) @@ -128,34 +125,22 @@ type wechatBindRequest struct { func WeChatBind(c *gin.Context) { if !common.WeChatAuthEnabled { - c.JSON(http.StatusOK, gin.H{ - "message": "管理员未开启通过微信登录以及注册", - "success": false, - }) + common.ApiErrorI18n(c, i18n.MsgWeChatNotEnabled) return } var req wechatBindRequest if err := common.DecodeJson(c.Request.Body, &req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "success": false, - "message": "无效的请求", - }) + common.ApiErrorI18n(c, i18n.MsgInvalidParams) return } code := req.Code wechatId, err := getWeChatIdByCode(code) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "message": err.Error(), - "success": false, - }) + apiWeChatError(c, err) return } if model.IsWeChatIdAlreadyTaken(wechatId) { - c.JSON(http.StatusOK, gin.H{ - "success": false, - "message": "该微信账号已被绑定", - }) + common.ApiErrorI18n(c, i18n.MsgWeChatAccountUsed) return } session := sessions.Default(c) diff --git a/i18n/keys.go b/i18n/keys.go index 6cf5c1bdc33..87ead3b5365 100644 --- a/i18n/keys.go +++ b/i18n/keys.go @@ -329,4 +329,11 @@ const ( MsgCustomOAuthHasBindings = "custom_oauth.has_bindings" MsgCustomOAuthBindingNotFound = "custom_oauth.binding_not_found" MsgCustomOAuthProviderIdInvalid = "custom_oauth.provider_id_field_invalid" + MsgCustomOAuthUnbindSuccess = "custom_oauth.unbind_success" +) + +// WeChat auth related messages +const ( + MsgWeChatNotEnabled = "wechat.not_enabled" + MsgWeChatAccountUsed = "wechat.account_used" ) diff --git a/i18n/locales/en.yaml b/i18n/locales/en.yaml index 198aa27412b..65b311f7980 100644 --- a/i18n/locales/en.yaml +++ b/i18n/locales/en.yaml @@ -277,3 +277,8 @@ custom_oauth.name_empty: "Provider name cannot be empty" custom_oauth.has_bindings: "Cannot delete provider with existing user bindings" custom_oauth.binding_not_found: "OAuth binding not found" custom_oauth.provider_id_field_invalid: "Could not extract user ID from provider response" +custom_oauth.unbind_success: "OAuth account unbound successfully" + +# WeChat auth messages +wechat.not_enabled: "WeChat login and registration are not enabled" +wechat.account_used: "This WeChat account has already been bound" diff --git a/i18n/locales/zh-CN.yaml b/i18n/locales/zh-CN.yaml index 45a10a584e5..dd396427e7a 100644 --- a/i18n/locales/zh-CN.yaml +++ b/i18n/locales/zh-CN.yaml @@ -278,3 +278,8 @@ custom_oauth.name_empty: "提供商名称不能为空" custom_oauth.has_bindings: "无法删除已有用户绑定的提供商" custom_oauth.binding_not_found: "OAuth 绑定不存在" custom_oauth.provider_id_field_invalid: "无法从提供商响应中提取用户 ID" +custom_oauth.unbind_success: "OAuth 账户解绑成功" + +# WeChat auth messages +wechat.not_enabled: "管理员未开启通过微信登录以及注册" +wechat.account_used: "该微信账户已被绑定" diff --git a/i18n/locales/zh-TW.yaml b/i18n/locales/zh-TW.yaml index ad5a6eae322..07117ca9c1d 100644 --- a/i18n/locales/zh-TW.yaml +++ b/i18n/locales/zh-TW.yaml @@ -278,3 +278,8 @@ custom_oauth.name_empty: "供應者名稱不能為空" custom_oauth.has_bindings: "無法刪除已有使用者綁定的供應者" custom_oauth.binding_not_found: "OAuth 綁定不存在" custom_oauth.provider_id_field_invalid: "無法從供應者響應中提取使用者 ID" +custom_oauth.unbind_success: "OAuth 帳號解除綁定成功" + +# WeChat auth messages +wechat.not_enabled: "管理員未開啟透過微信登入以及註冊" +wechat.account_used: "該微信帳號已被綁定" From a122dff464194aefb9773ed803245977a84fe96e Mon Sep 17 00:00:00 2001 From: Neo Date: Sun, 17 May 2026 13:12:42 -0700 Subject: [PATCH 2/2] [GPT-5 Codex] fix auth: use JSON wrapper - Decode WeChat login responses through common.DecodeJson. - Remove direct encoding/json use from the touched controller. --- controller/wechat.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/controller/wechat.go b/controller/wechat.go index 279eedda8f5..4107d4c566f 100644 --- a/controller/wechat.go +++ b/controller/wechat.go @@ -1,7 +1,6 @@ package controller import ( - "encoding/json" "errors" "fmt" "net/http" @@ -46,7 +45,7 @@ func getWeChatIdByCode(code string) (string, error) { } defer httpResponse.Body.Close() var res wechatLoginResponse - err = json.NewDecoder(httpResponse.Body).Decode(&res) + err = common.DecodeJson(httpResponse.Body, &res) if err != nil { return "", err }