fix(phase-4): add DB error checking, mask sensitive auth tokens in API and middleware logs
CI / Lint (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Build (push) Has been cancelled

This commit is contained in:
newkirk
2026-07-21 13:23:02 -04:00
parent 700b7cd5d6
commit a187d8e20e
4 changed files with 39 additions and 13 deletions
+5 -1
View File
@@ -72,7 +72,11 @@ func AuthMiddleware(database *db.DB, requireAuth bool) gin.HandlerFunc {
c.Next()
} else {
log.Printf("Token not found, inactive or error in DB: %s (err: %v)", token, err)
maskedToken := "••••"
if len(token) > 8 {
maskedToken = token[:3] + "••••" + token[len(token)-4:]
}
log.Printf("Token not found, inactive or error in DB: %s (err: %v)", maskedToken, err)
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
"error": gin.H{
"message": "Invalid or inactive client token.",
+2 -5
View File
@@ -113,14 +113,11 @@ func (p *DeepSeekProvider) ChatCompletion(ctx context.Context, req *models.Unifi
}
if !resp.IsSuccess() {
var msg string
if resp.RawBody() != nil {
msg := resp.String()
if msg == "" && resp.RawBody() != nil {
bodyBytes, _ := io.ReadAll(resp.RawBody())
msg = string(bodyBytes)
}
if msg == "" {
msg = resp.String()
}
return nil, fmt.Errorf("DeepSeek API error (%d): %s", resp.StatusCode(), msg)
}
+11 -2
View File
@@ -67,18 +67,27 @@ func (s *Server) handleGetSettings(c *gin.Context) {
providerCount := 0
modelCount := 0
s.registryMu.RLock()
defer s.registryMu.RUnlock()
if s.registry != nil {
providerCount = len(s.registry.Providers)
for _, p := range s.registry.Providers {
modelCount += len(p.Models)
}
}
s.registryMu.RUnlock()
maskedTokens := make([]string, len(s.cfg.Server.AuthTokens))
for i, token := range s.cfg.Server.AuthTokens {
if len(token) > 8 {
maskedTokens[i] = token[:3] + "••••" + token[len(token)-4:]
} else {
maskedTokens[i] = "••••"
}
}
c.JSON(http.StatusOK, SuccessResponse(gin.H{
"server": gin.H{
"version": "1.0.0-go",
"auth_tokens": s.cfg.Server.AuthTokens,
"auth_tokens": maskedTokens,
},
"database": gin.H{
"type": "sqlite",
+21 -5
View File
@@ -70,17 +70,33 @@ func (s *Server) handleUpdateUser(c *gin.Context) {
}
if req.DisplayName != nil {
s.database.Exec("UPDATE users SET display_name = ? WHERE id = ?", req.DisplayName, id)
if _, err := s.database.Exec("UPDATE users SET display_name = ? WHERE id = ?", req.DisplayName, id); err != nil {
c.JSON(http.StatusInternalServerError, ErrorResponse("Failed to update display name"))
return
}
}
if req.Role != nil {
s.database.Exec("UPDATE users SET role = ? WHERE id = ?", req.Role, id)
if _, err := s.database.Exec("UPDATE users SET role = ? WHERE id = ?", req.Role, id); err != nil {
c.JSON(http.StatusInternalServerError, ErrorResponse("Failed to update role"))
return
}
}
if req.MustChangePassword != nil {
s.database.Exec("UPDATE users SET must_change_password = ? WHERE id = ?", req.MustChangePassword, id)
if _, err := s.database.Exec("UPDATE users SET must_change_password = ? WHERE id = ?", req.MustChangePassword, id); err != nil {
c.JSON(http.StatusInternalServerError, ErrorResponse("Failed to update password flag"))
return
}
}
if req.Password != nil {
hash, _ := bcrypt.GenerateFromPassword([]byte(*req.Password), 12)
s.database.Exec("UPDATE users SET password_hash = ? WHERE id = ?", string(hash), id)
hash, err := bcrypt.GenerateFromPassword([]byte(*req.Password), 12)
if err != nil {
c.JSON(http.StatusInternalServerError, ErrorResponse("Failed to hash password"))
return
}
if _, err := s.database.Exec("UPDATE users SET password_hash = ? WHERE id = ?", string(hash), id); err != nil {
c.JSON(http.StatusInternalServerError, ErrorResponse("Failed to update password"))
return
}
}
c.JSON(http.StatusOK, SuccessResponse(gin.H{"message": "User updated"}))