fix: complete audit security and frontend gaps

This commit is contained in:
2026-07-18 18:02:29 +08:00
parent 79feb20688
commit b7a84d31ea
28 changed files with 576 additions and 88 deletions

View File

@@ -5,6 +5,7 @@ import (
"strconv"
"github.com/gin-gonic/gin"
"senlinai-agent/backend/internal/auth"
)
type Handler struct {
@@ -22,6 +23,11 @@ func (h *Handler) Register(router gin.IRouter) {
}
func (h *Handler) capture(c *gin.Context) {
userID, ok := auth.CurrentUserID(c)
if !ok {
c.JSON(http.StatusUnauthorized, gin.H{"error": "missing current user"})
return
}
projectID, err := strconv.ParseUint(c.Param("projectID"), 10, 64)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid project id"})
@@ -36,7 +42,7 @@ func (h *Handler) capture(c *gin.Context) {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request"})
return
}
item, err := h.service.Capture(CaptureInput{ProjectID: uint(projectID), UserID: 1, SourceType: input.SourceType, Title: input.Title, Body: input.Body})
item, err := h.service.Capture(CaptureInput{ProjectID: uint(projectID), UserID: userID, SourceType: input.SourceType, Title: input.Title, Body: input.Body})
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
@@ -45,12 +51,17 @@ func (h *Handler) capture(c *gin.Context) {
}
func (h *Handler) analyze(c *gin.Context) {
userID, ok := auth.CurrentUserID(c)
if !ok {
c.JSON(http.StatusUnauthorized, gin.H{"error": "missing current user"})
return
}
itemID, err := strconv.ParseUint(c.Param("id"), 10, 64)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid inbox id"})
return
}
suggestions, err := h.service.Analyze(uint(itemID), 1)
suggestions, err := h.service.Analyze(uint(itemID), userID)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return

View File

@@ -77,18 +77,19 @@ func (s *Service) Confirm(itemID uint, selected []Suggestion) error {
if err := tx.First(&item, itemID).Error; err != nil {
return err
}
sourceInboxItemID := item.ID
for _, suggestion := range selected {
switch suggestion.Kind {
case "task":
if err := tx.Create(&domain.Task{ProjectID: item.ProjectID, CreatedBy: item.CreatedBy, Title: suggestion.Title, Description: suggestion.Body}).Error; err != nil {
if err := tx.Create(&domain.Task{ProjectID: item.ProjectID, CreatedBy: item.CreatedBy, SourceInboxItemID: &sourceInboxItemID, Title: suggestion.Title, Description: suggestion.Body}).Error; err != nil {
return err
}
case "note":
if err := tx.Create(&domain.Note{ProjectID: item.ProjectID, CreatedBy: item.CreatedBy, Title: suggestion.Title, Markdown: suggestion.Body}).Error; err != nil {
if err := tx.Create(&domain.Note{ProjectID: item.ProjectID, CreatedBy: item.CreatedBy, SourceInboxItemID: &sourceInboxItemID, Title: suggestion.Title, Markdown: suggestion.Body}).Error; err != nil {
return err
}
case "source":
if err := tx.Create(&domain.Source{ProjectID: item.ProjectID, CreatedBy: item.CreatedBy, Kind: "link", Title: suggestion.Title, ContentText: suggestion.Body}).Error; err != nil {
if err := tx.Create(&domain.Source{ProjectID: item.ProjectID, CreatedBy: item.CreatedBy, SourceInboxItemID: &sourceInboxItemID, Kind: "link", Title: suggestion.Title, ContentText: suggestion.Body}).Error; err != nil {
return err
}
default:

View File

@@ -44,6 +44,8 @@ func TestConfirmCreatesSelectedObjectsAndKeepsInboxItem(t *testing.T) {
require.NoError(t, database.Find(&tasks).Error)
require.Len(t, tasks, 1)
require.Equal(t, "跟进报价", tasks[0].Title)
require.NotNil(t, tasks[0].SourceInboxItemID)
require.Equal(t, item.ID, *tasks[0].SourceInboxItemID)
var reloaded domain.InboxItem
require.NoError(t, database.First(&reloaded, item.ID).Error)
require.Equal(t, "processed", reloaded.Status)