diff --git a/internal/api/routes/files.go b/internal/api/routes/files.go index 3123de0..0d987f4 100644 --- a/internal/api/routes/files.go +++ b/internal/api/routes/files.go @@ -47,7 +47,7 @@ func RegisterFileRoutes(cfg *types.StereoConfig, api *gin.RouterGroup) { } fileMeta := types.File{ - Name: file.Filename, + ID: uid + "_" + file.Filename, Owner: uid, CreatedAt: time.Now(), Size: file.Size, @@ -58,134 +58,68 @@ func RegisterFileRoutes(cfg *types.StereoConfig, api *gin.RouterGroup) { return } - c.JSON(200, gin.H{"message": "file uploaded successfully", "name": fileMeta.Name}) + c.JSON(200, gin.H{"message": "file uploaded successfully", "file_id": fileMeta.ID}) }) - // api.DELETE("/delete", auth.JwtMiddleware(cfg.JWTSecret), func(c *gin.Context) { - // claims := c.MustGet("claims").(jwt.MapClaims) - // user := claims["user"].(auth.User) - - // uid := user.ID - // if uid == "" { - // c.JSON(401, gin.H{"error": "unauthorized"}) - // return - // } - - // var response struct { - // Name string `json:"name" binding:"required"` - // ID string `json:"id" binding:"required"` - // } - - // if err := c.ShouldBindJSON(&response); err != nil { - // c.JSON(400, gin.H{"error": "name is required"}) - // return - // } - - // name := response.Name - // if name == "" { - // c.JSON(400, gin.H{"error": "name cannot be empty"}) - // return - // } - - // resID := response.ID - // if resID == "" { - // c.JSON(400, gin.H{"error": "id cannot be empty"}) - // return - // } - - // if resID != uid { - // c.JSON(403, gin.H{"error": "you can only delete your own files"}) - // return - // } - - // filePath := filepath.Join(cfg.ImagePath, uid, name) - // if err := os.Remove(filePath); err != nil { - // c.JSON(500, gin.H{"error": "failed to delete file"}) - // return - // } - - // if err := cfg.Database.Where("name = ?", name).Where("owner = ?", uid).Delete(&types.File{}).Error; err != nil { - // c.JSON(500, gin.H{"error": "failed to delete file metadata"}) - // return - // } - - // c.JSON(200, gin.H{"message": "file deleted successfully"}) - // }) - - api.DELETE("/:uid/:name", auth.JwtMiddleware(cfg.JWTSecret), func(c *gin.Context) { + api.DELETE("/delete", auth.JwtMiddleware(cfg.JWTSecret), func(c *gin.Context) { claims := c.MustGet("claims").(jwt.MapClaims) user := claims["user"].(auth.User) - uid := c.Param("uid") - uid = strings.TrimSpace(uid) + uid := user.ID if uid == "" { - c.JSON(400, gin.H{"error": "uid is required"}) + c.JSON(401, gin.H{"error": "unauthorized"}) return } - if uid != user.ID { + var response struct { + FileID string `json:"file_id" binding:"required"` + } + + if err := c.ShouldBindJSON(&response); err != nil { + c.JSON(400, gin.H{"error": "file_id is required"}) + return + } + + resfID := response.FileID + if resfID == "" { + c.JSON(400, gin.H{"error": "file_id cannot be empty"}) + return + } + + parts := strings.SplitN(resfID, "_", 2) + if len(parts) != 2 { + c.JSON(400, gin.H{"error": "invalid file_id format"}) + return + } + + fileID, filename := parts[0], parts[1] + if fileID != uid { c.JSON(403, gin.H{"error": "you can only delete your own files"}) return } - filename := c.Param("name") - filename = strings.TrimSpace(filename) - if filename == "" { - c.JSON(400, gin.H{"error": "filename is required"}) - return - } - - path := filepath.Join(cfg.ImagePath, uid, filename) - if _, err := os.Stat(path); os.IsNotExist(err) { - c.JSON(404, gin.H{"error": "file not found"}) - return - } - - if err := os.Remove(path); err != nil { + filePath := filepath.Join(cfg.ImagePath, uid, filename) + if err := os.Remove(filePath); err != nil { c.JSON(500, gin.H{"error": "failed to delete file"}) return } - if err := cfg.Database.Where("owner = ? AND name = ?", uid, filename).Delete(&types.File{}).Error; err != nil { + + if err := cfg.Database.Where("id = ?", resfID).Delete(&types.File{}).Error; err != nil { c.JSON(500, gin.H{"error": "failed to delete file metadata"}) return } + c.JSON(200, gin.H{"message": "file deleted successfully"}) }) - api.GET("/:uid/:name", func(c *gin.Context) { - uid := c.Param("uid") - uid = strings.TrimSpace(uid) - if uid == "" { - c.JSON(400, gin.H{"error": "uid is required"}) + api.GET("/:name", func(c *gin.Context) { + name := c.Param("name") + parts := strings.SplitN(name, "_", 2) + if len(parts) != 2 { + c.JSON(400, gin.H{"error": "invalid file name"}) return } - - filename := c.Param("name") - filename = strings.TrimSpace(filename) - - safe := "" - for _, r := range filename { - if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || - (r >= '0' && r <= '9') || r == '_' || r == '.' || r == '-' { - safe += string(r) - } else { - safe += "_" - } - } - filename = safe - - // parts := strings.SplitN(name, "_", 2) - // if len(parts) != 2 { - // c.JSON(400, gin.H{"error": "invalid file name"}) - // return - // } - - // uid, filename := parts[0], parts[1] - // if uid == "" || filename == "" { - // c.JSON(400, gin.H{"error": "invalid file name"}) - // return - // } - + uid, filename := parts[0], parts[1] path := filepath.Join(cfg.ImagePath, uid, filename) if _, err := os.Stat(path); err != nil { c.JSON(404, gin.H{"error": "file not found"}) diff --git a/internal/types/types.go b/internal/types/types.go index 9dd0178..abae4ee 100644 --- a/internal/types/types.go +++ b/internal/types/types.go @@ -25,7 +25,7 @@ type StereoConfig struct { } type File struct { - Name string `gorm:"primaryKey"` + ID string `gorm:"primaryKey"` Owner string `gorm:"not null;index"` Size int64 `gorm:"not null;type:bigint"` CreatedAt time.Time `gorm:"autoCreateTime"`