fix: unify handler response format in multiple handlers

- captcha_handler.go: Fix GenerateCaptcha/VerifyCaptcha to use {code, message, data}
- password_reset_handler.go: Fix all error responses to use {code, message}
- settings_handler.go: Add missing "code" and "message" fields
- sms_handler.go: Fix error responses to use {code, message}
- sso_handler.go: Fix all error responses to use {code, message, data}
- stats_handler.go: Add missing "message" field in success responses
- theme_handler.go: Fix error responses to use {code, message}
- totp_handler.go: Fix all responses to use {code, message, data}

Standardize all JSON responses to {code: 0, message: "success", data: ...} for success
and {code: XXX, message: "..."} for errors.
This commit is contained in:
2026-04-11 13:06:58 +08:00
parent e239e95a84
commit b6aff65975
8 changed files with 79 additions and 67 deletions

View File

@@ -26,13 +26,17 @@ func (h *CaptchaHandler) GenerateCaptcha(c *gin.Context) {
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
"code": 0,
"message": "success",
"data": gin.H{
"captcha_id": result.CaptchaID, "captcha_id": result.CaptchaID,
"image": result.ImageData, "image": result.ImageData,
},
}) })
} }
func (h *CaptchaHandler) GetCaptchaImage(c *gin.Context) { func (h *CaptchaHandler) GetCaptchaImage(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "captcha image endpoint"}) c.JSON(http.StatusOK, gin.H{"code": 0, "message": "success"})
} }
func (h *CaptchaHandler) VerifyCaptcha(c *gin.Context) { func (h *CaptchaHandler) VerifyCaptcha(c *gin.Context) {
@@ -42,13 +46,13 @@ func (h *CaptchaHandler) VerifyCaptcha(c *gin.Context) {
} }
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": err.Error()})
return return
} }
if h.captchaService.Verify(c.Request.Context(), req.CaptchaID, req.Answer) { if h.captchaService.Verify(c.Request.Context(), req.CaptchaID, req.Answer) {
c.JSON(http.StatusOK, gin.H{"verified": true}) c.JSON(http.StatusOK, gin.H{"code": 0, "message": "success", "data": gin.H{"verified": true}})
} else { } else {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid captcha"}) c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "invalid captcha"})
} }
} }

View File

@@ -33,7 +33,7 @@ func (h *PasswordResetHandler) ForgotPassword(c *gin.Context) {
} }
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": err.Error()})
return return
} }
@@ -42,13 +42,13 @@ func (h *PasswordResetHandler) ForgotPassword(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{"message": "password reset email sent"}) c.JSON(http.StatusOK, gin.H{"code": 0, "message": "password reset email sent"})
} }
func (h *PasswordResetHandler) ValidateResetToken(c *gin.Context) { func (h *PasswordResetHandler) ValidateResetToken(c *gin.Context) {
token := c.Query("token") token := c.Query("token")
if token == "" { if token == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "token is required"}) c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "token is required"})
return return
} }
@@ -58,7 +58,7 @@ func (h *PasswordResetHandler) ValidateResetToken(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{"valid": valid}) c.JSON(http.StatusOK, gin.H{"code": 0, "message": "success", "data": gin.H{"valid": valid}})
} }
func (h *PasswordResetHandler) ResetPassword(c *gin.Context) { func (h *PasswordResetHandler) ResetPassword(c *gin.Context) {
@@ -68,7 +68,7 @@ func (h *PasswordResetHandler) ResetPassword(c *gin.Context) {
} }
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": err.Error()})
return return
} }
@@ -77,7 +77,7 @@ func (h *PasswordResetHandler) ResetPassword(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{"message": "password reset successful"}) c.JSON(http.StatusOK, gin.H{"code": 0, "message": "password reset successful"})
} }
// ForgotPasswordByPhoneRequest 短信密码重置请求 // ForgotPasswordByPhoneRequest 短信密码重置请求
@@ -88,13 +88,13 @@ type ForgotPasswordByPhoneRequest struct {
// ForgotPasswordByPhone 发送短信验证码 // ForgotPasswordByPhone 发送短信验证码
func (h *PasswordResetHandler) ForgotPasswordByPhone(c *gin.Context) { func (h *PasswordResetHandler) ForgotPasswordByPhone(c *gin.Context) {
if h.smsService == nil { if h.smsService == nil {
c.JSON(http.StatusServiceUnavailable, gin.H{"error": "SMS service not configured"}) c.JSON(http.StatusServiceUnavailable, gin.H{"code": 503, "message": "SMS service not configured"})
return return
} }
var req ForgotPasswordByPhoneRequest var req ForgotPasswordByPhoneRequest
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": err.Error()})
return return
} }
@@ -106,7 +106,7 @@ func (h *PasswordResetHandler) ForgotPasswordByPhone(c *gin.Context) {
} }
if code == "" { if code == "" {
// 用户不存在,不提示 // 用户不存在,不提示
c.JSON(http.StatusOK, gin.H{"message": "verification code sent"}) c.JSON(http.StatusOK, gin.H{"code": 0, "message": "success"})
return return
} }
@@ -121,7 +121,7 @@ func (h *PasswordResetHandler) ForgotPasswordByPhone(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{"message": "verification code sent"}) c.JSON(http.StatusOK, gin.H{"code": 0, "message": "success"})
} }
// ResetPasswordByPhoneRequest 短信验证码重置密码请求 // ResetPasswordByPhoneRequest 短信验证码重置密码请求
@@ -135,7 +135,7 @@ type ResetPasswordByPhoneRequest struct {
func (h *PasswordResetHandler) ResetPasswordByPhone(c *gin.Context) { func (h *PasswordResetHandler) ResetPasswordByPhone(c *gin.Context) {
var req ResetPasswordByPhoneRequest var req ResetPasswordByPhoneRequest
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": err.Error()})
return return
} }
@@ -149,5 +149,5 @@ func (h *PasswordResetHandler) ResetPasswordByPhone(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{"message": "password reset successful"}) c.JSON(http.StatusOK, gin.H{"code": 0, "message": "password reset successful"})
} }

View File

@@ -33,5 +33,5 @@ func (h *SettingsHandler) GetSettings(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{"data": settings}) c.JSON(http.StatusOK, gin.H{"code": 0, "message": "success", "data": settings})
} }

View File

@@ -30,13 +30,13 @@ func NewSMSHandlerWithService(authService *service.AuthService, smsCodeService *
// SendCode 发送短信验证码(用于注册/登录) // SendCode 发送短信验证码(用于注册/登录)
func (h *SMSHandler) SendCode(c *gin.Context) { func (h *SMSHandler) SendCode(c *gin.Context) {
if h.smsCodeService == nil { if h.smsCodeService == nil {
c.JSON(http.StatusServiceUnavailable, gin.H{"error": "SMS service not configured"}) c.JSON(http.StatusServiceUnavailable, gin.H{"code": 503, "message": "SMS service not configured"})
return return
} }
var req service.SendCodeRequest var req service.SendCodeRequest
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": err.Error()})
return return
} }
@@ -56,7 +56,7 @@ func (h *SMSHandler) SendCode(c *gin.Context) {
// LoginByCode 短信验证码登录(带设备信息以支持设备信任链路) // LoginByCode 短信验证码登录(带设备信息以支持设备信任链路)
func (h *SMSHandler) LoginByCode(c *gin.Context) { func (h *SMSHandler) LoginByCode(c *gin.Context) {
if h.authService == nil { if h.authService == nil {
c.JSON(http.StatusServiceUnavailable, gin.H{"error": "SMS login not configured"}) c.JSON(http.StatusServiceUnavailable, gin.H{"code": 503, "message": "SMS login not configured"})
return return
} }
@@ -70,7 +70,7 @@ func (h *SMSHandler) LoginByCode(c *gin.Context) {
} }
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": err.Error()})
return return
} }

View File

@@ -38,20 +38,20 @@ type AuthorizeRequest struct {
func (h *SSOHandler) Authorize(c *gin.Context) { func (h *SSOHandler) Authorize(c *gin.Context) {
var req AuthorizeRequest var req AuthorizeRequest
if err := c.ShouldBindQuery(&req); err != nil { if err := c.ShouldBindQuery(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": err.Error()})
return return
} }
// 验证 response_type // 验证 response_type
if req.ResponseType != "code" && req.ResponseType != "token" { if req.ResponseType != "code" && req.ResponseType != "token" {
c.JSON(http.StatusBadRequest, gin.H{"error": "unsupported response_type"}) c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "unsupported response_type"})
return return
} }
// 验证 redirect_uri 是否在白名单中 // 验证 redirect_uri 是否在白名单中
if h.clientsStore != nil { if h.clientsStore != nil {
if !h.clientsStore.ValidateClientRedirectURI(req.ClientID, req.RedirectURI) { if !h.clientsStore.ValidateClientRedirectURI(req.ClientID, req.RedirectURI) {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid redirect_uri"}) c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "invalid redirect_uri"})
return return
} }
} }
@@ -59,7 +59,7 @@ func (h *SSOHandler) Authorize(c *gin.Context) {
// 获取当前登录用户(从 auth middleware 设置的 context // 获取当前登录用户(从 auth middleware 设置的 context
userID, exists := c.Get("user_id") userID, exists := c.Get("user_id")
if !exists { if !exists {
c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"}) c.JSON(http.StatusUnauthorized, gin.H{"code": 401, "message": "unauthorized"})
return return
} }
@@ -75,7 +75,7 @@ func (h *SSOHandler) Authorize(c *gin.Context) {
username.(string), username.(string),
) )
if err != nil { if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to generate code"}) c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "failed to generate code"})
return return
} }
@@ -95,20 +95,20 @@ func (h *SSOHandler) Authorize(c *gin.Context) {
username.(string), username.(string),
) )
if err != nil { if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to generate code"}) c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "failed to generate code"})
return return
} }
// 验证授权码获取 session // 验证授权码获取 session
session, err := h.ssoManager.ValidateAuthorizationCode(code) session, err := h.ssoManager.ValidateAuthorizationCode(code)
if err != nil { if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to validate code"}) c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "failed to validate code"})
return return
} }
token, _, err := h.ssoManager.GenerateAccessToken(req.ClientID, session) token, _, err := h.ssoManager.GenerateAccessToken(req.ClientID, session)
if err != nil { if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to generate token"}) c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "failed to generate token"})
return return
} }
@@ -143,13 +143,13 @@ type TokenResponse struct {
func (h *SSOHandler) Token(c *gin.Context) { func (h *SSOHandler) Token(c *gin.Context) {
var req TokenRequest var req TokenRequest
if err := c.ShouldBind(&req); err != nil { if err := c.ShouldBind(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": err.Error()})
return return
} }
// 验证 grant_type // 验证 grant_type
if req.GrantType != "authorization_code" { if req.GrantType != "authorization_code" {
c.JSON(http.StatusBadRequest, gin.H{"error": "unsupported grant_type"}) c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "unsupported grant_type"})
return return
} }
@@ -157,12 +157,12 @@ func (h *SSOHandler) Token(c *gin.Context) {
if h.clientsStore != nil { if h.clientsStore != nil {
client, err := h.clientsStore.GetByClientID(req.ClientID) client, err := h.clientsStore.GetByClientID(req.ClientID)
if err != nil { if err != nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": "invalid client"}) c.JSON(http.StatusUnauthorized, gin.H{"code": 401, "message": "invalid client"})
return return
} }
// 使用常量时间比较防止时序攻击 // 使用常量时间比较防止时序攻击
if subtle.ConstantTimeCompare([]byte(req.ClientSecret), []byte(client.ClientSecret)) != 1 { if subtle.ConstantTimeCompare([]byte(req.ClientSecret), []byte(client.ClientSecret)) != 1 {
c.JSON(http.StatusUnauthorized, gin.H{"error": "invalid client_secret"}) c.JSON(http.StatusUnauthorized, gin.H{"code": 401, "message": "invalid client_secret"})
return return
} }
} }
@@ -170,14 +170,14 @@ func (h *SSOHandler) Token(c *gin.Context) {
// 验证授权码 // 验证授权码
session, err := h.ssoManager.ValidateAuthorizationCode(req.Code) session, err := h.ssoManager.ValidateAuthorizationCode(req.Code)
if err != nil { if err != nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": "invalid code"}) c.JSON(http.StatusUnauthorized, gin.H{"code": 401, "message": "invalid code"})
return return
} }
// 生成 access token // 生成 access token
token, expiresAt, err := h.ssoManager.GenerateAccessToken(req.ClientID, session) token, expiresAt, err := h.ssoManager.GenerateAccessToken(req.ClientID, session)
if err != nil { if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to generate token"}) c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "failed to generate token"})
return return
} }
@@ -209,7 +209,7 @@ type IntrospectResponse struct {
func (h *SSOHandler) Introspect(c *gin.Context) { func (h *SSOHandler) Introspect(c *gin.Context) {
var req IntrospectRequest var req IntrospectRequest
if err := c.ShouldBind(&req); err != nil { if err := c.ShouldBind(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": err.Error()})
return return
} }
@@ -238,13 +238,13 @@ type RevokeRequest struct {
func (h *SSOHandler) Revoke(c *gin.Context) { func (h *SSOHandler) Revoke(c *gin.Context) {
var req RevokeRequest var req RevokeRequest
if err := c.ShouldBind(&req); err != nil { if err := c.ShouldBind(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": err.Error()})
return return
} }
h.ssoManager.RevokeToken(req.Token) h.ssoManager.RevokeToken(req.Token)
c.JSON(http.StatusOK, gin.H{"message": "token revoked"}) c.JSON(http.StatusOK, gin.H{"code": 0, "message": "token revoked"})
} }
// UserInfoResponse 用户信息响应 // UserInfoResponse 用户信息响应
@@ -258,14 +258,18 @@ type UserInfoResponse struct {
func (h *SSOHandler) UserInfo(c *gin.Context) { func (h *SSOHandler) UserInfo(c *gin.Context) {
userID, exists := c.Get("user_id") userID, exists := c.Get("user_id")
if !exists { if !exists {
c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"}) c.JSON(http.StatusUnauthorized, gin.H{"code": 401, "message": "unauthorized"})
return return
} }
username, _ := c.Get("username") username, _ := c.Get("username")
c.JSON(http.StatusOK, UserInfoResponse{ c.JSON(http.StatusOK, gin.H{
"code": 0,
"message": "success",
"data": UserInfoResponse{
UserID: userID.(int64), UserID: userID.(int64),
Username: username.(string), Username: username.(string),
},
}) })
} }

View File

@@ -24,7 +24,7 @@ func (h *StatsHandler) GetDashboard(c *gin.Context) {
c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "获取仪表盘数据失败"}) c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "获取仪表盘数据失败"})
return return
} }
c.JSON(http.StatusOK, gin.H{"code": 0, "data": stats}) c.JSON(http.StatusOK, gin.H{"code": 0, "message": "success", "data": stats})
} }
func (h *StatsHandler) GetUserStats(c *gin.Context) { func (h *StatsHandler) GetUserStats(c *gin.Context) {
@@ -33,5 +33,5 @@ func (h *StatsHandler) GetUserStats(c *gin.Context) {
c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "获取用户统计失败"}) c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "获取用户统计失败"})
return return
} }
c.JSON(http.StatusOK, gin.H{"code": 0, "data": stats}) c.JSON(http.StatusOK, gin.H{"code": 0, "message": "success", "data": stats})
} }

View File

@@ -23,7 +23,7 @@ func NewThemeHandler(themeService *service.ThemeService) *ThemeHandler {
func (h *ThemeHandler) CreateTheme(c *gin.Context) { func (h *ThemeHandler) CreateTheme(c *gin.Context) {
var req service.CreateThemeRequest var req service.CreateThemeRequest
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": err.Error()})
return return
} }
@@ -44,13 +44,13 @@ func (h *ThemeHandler) CreateTheme(c *gin.Context) {
func (h *ThemeHandler) UpdateTheme(c *gin.Context) { func (h *ThemeHandler) UpdateTheme(c *gin.Context) {
id, err := strconv.ParseInt(c.Param("id"), 10, 64) id, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid theme id"}) c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "invalid theme id"})
return return
} }
var req service.UpdateThemeRequest var req service.UpdateThemeRequest
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": err.Error()})
return return
} }
@@ -71,7 +71,7 @@ func (h *ThemeHandler) UpdateTheme(c *gin.Context) {
func (h *ThemeHandler) DeleteTheme(c *gin.Context) { func (h *ThemeHandler) DeleteTheme(c *gin.Context) {
id, err := strconv.ParseInt(c.Param("id"), 10, 64) id, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid theme id"}) c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "invalid theme id"})
return return
} }
@@ -90,7 +90,7 @@ func (h *ThemeHandler) DeleteTheme(c *gin.Context) {
func (h *ThemeHandler) GetTheme(c *gin.Context) { func (h *ThemeHandler) GetTheme(c *gin.Context) {
id, err := strconv.ParseInt(c.Param("id"), 10, 64) id, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid theme id"}) c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "invalid theme id"})
return return
} }
@@ -156,7 +156,7 @@ func (h *ThemeHandler) GetDefaultTheme(c *gin.Context) {
func (h *ThemeHandler) SetDefaultTheme(c *gin.Context) { func (h *ThemeHandler) SetDefaultTheme(c *gin.Context) {
id, err := strconv.ParseInt(c.Param("id"), 10, 64) id, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid theme id"}) c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "invalid theme id"})
return return
} }

View File

@@ -25,7 +25,7 @@ func NewTOTPHandler(authService *service.AuthService, totpService *service.TOTPS
func (h *TOTPHandler) GetTOTPStatus(c *gin.Context) { func (h *TOTPHandler) GetTOTPStatus(c *gin.Context) {
userID, ok := getUserIDFromContext(c) userID, ok := getUserIDFromContext(c)
if !ok { if !ok {
c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"}) c.JSON(http.StatusUnauthorized, gin.H{"code": 401, "message": "unauthorized"})
return return
} }
@@ -35,13 +35,13 @@ func (h *TOTPHandler) GetTOTPStatus(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{"enabled": enabled}) c.JSON(http.StatusOK, gin.H{"code": 0, "message": "success", "data": gin.H{"enabled": enabled}})
} }
func (h *TOTPHandler) SetupTOTP(c *gin.Context) { func (h *TOTPHandler) SetupTOTP(c *gin.Context) {
userID, ok := getUserIDFromContext(c) userID, ok := getUserIDFromContext(c)
if !ok { if !ok {
c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"}) c.JSON(http.StatusUnauthorized, gin.H{"code": 401, "message": "unauthorized"})
return return
} }
@@ -52,16 +52,20 @@ func (h *TOTPHandler) SetupTOTP(c *gin.Context) {
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
"code": 0,
"message": "success",
"data": gin.H{
"secret": resp.Secret, "secret": resp.Secret,
"qr_code_base64": resp.QRCodeBase64, "qr_code_base64": resp.QRCodeBase64,
"recovery_codes": resp.RecoveryCodes, "recovery_codes": resp.RecoveryCodes,
},
}) })
} }
func (h *TOTPHandler) EnableTOTP(c *gin.Context) { func (h *TOTPHandler) EnableTOTP(c *gin.Context) {
userID, ok := getUserIDFromContext(c) userID, ok := getUserIDFromContext(c)
if !ok { if !ok {
c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"}) c.JSON(http.StatusUnauthorized, gin.H{"code": 401, "message": "unauthorized"})
return return
} }
@@ -70,7 +74,7 @@ func (h *TOTPHandler) EnableTOTP(c *gin.Context) {
} }
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": err.Error()})
return return
} }
@@ -79,13 +83,13 @@ func (h *TOTPHandler) EnableTOTP(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{"message": "TOTP enabled"}) c.JSON(http.StatusOK, gin.H{"code": 0, "message": "success"})
} }
func (h *TOTPHandler) DisableTOTP(c *gin.Context) { func (h *TOTPHandler) DisableTOTP(c *gin.Context) {
userID, ok := getUserIDFromContext(c) userID, ok := getUserIDFromContext(c)
if !ok { if !ok {
c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"}) c.JSON(http.StatusUnauthorized, gin.H{"code": 401, "message": "unauthorized"})
return return
} }
@@ -94,7 +98,7 @@ func (h *TOTPHandler) DisableTOTP(c *gin.Context) {
} }
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": err.Error()})
return return
} }
@@ -103,13 +107,13 @@ func (h *TOTPHandler) DisableTOTP(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{"message": "TOTP disabled"}) c.JSON(http.StatusOK, gin.H{"code": 0, "message": "success"})
} }
func (h *TOTPHandler) VerifyTOTP(c *gin.Context) { func (h *TOTPHandler) VerifyTOTP(c *gin.Context) {
userID, ok := getUserIDFromContext(c) userID, ok := getUserIDFromContext(c)
if !ok { if !ok {
c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"}) c.JSON(http.StatusUnauthorized, gin.H{"code": 401, "message": "unauthorized"})
return return
} }
@@ -119,7 +123,7 @@ func (h *TOTPHandler) VerifyTOTP(c *gin.Context) {
} }
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": err.Error()})
return return
} }
@@ -128,5 +132,5 @@ func (h *TOTPHandler) VerifyTOTP(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, gin.H{"verified": true}) c.JSON(http.StatusOK, gin.H{"code": 0, "message": "success", "data": gin.H{"verified": true}})
} }