refactor: simplify auth and subscription links
This commit is contained in:
@@ -1,133 +1,13 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
|
||||
"github.com/peterqiu0516/sub-store/internal/middleware"
|
||||
"github.com/peterqiu0516/sub-store/internal/model"
|
||||
)
|
||||
|
||||
// --- Share (download grant) handlers ---
|
||||
|
||||
func (d *Deps) HandleListShares(c fiber.Ctx) error {
|
||||
grants, err := d.GrantRepo.List()
|
||||
if err != nil {
|
||||
return failed(c, "Failed to list shares", 500)
|
||||
}
|
||||
return success(c, grants)
|
||||
}
|
||||
|
||||
func (d *Deps) HandleCreateShare(c fiber.Ctx) error {
|
||||
var input map[string]any
|
||||
if err := json.Unmarshal(c.Body(), &input); err != nil {
|
||||
return failed(c, "Invalid JSON", 400)
|
||||
}
|
||||
resourceType := getStringValue(input["resourceType"])
|
||||
if resourceType != "source" && resourceType != "collection" {
|
||||
return failed(c, "Share resourceType and resourceId are required", 400)
|
||||
}
|
||||
resourceId := getStringValue(input["resourceId"])
|
||||
if resourceId == "" {
|
||||
return failed(c, "Share resourceType and resourceId are required", 400)
|
||||
}
|
||||
// Check resource exists
|
||||
if resourceType == "source" {
|
||||
s, _ := d.SourceRepo.Get(resourceId)
|
||||
if s == nil {
|
||||
return failed(c, "Share resource does not exist", 404)
|
||||
}
|
||||
} else {
|
||||
col, _ := d.CollectionRepo.Get(resourceId)
|
||||
if col == nil {
|
||||
return failed(c, "Share resource does not exist", 404)
|
||||
}
|
||||
}
|
||||
target := ""
|
||||
if input["target"] != nil {
|
||||
target = model.NormalizeTargetAlias(input["target"])
|
||||
if input["target"] != "" && target == "" {
|
||||
return failed(c, "Unsupported target", 400)
|
||||
}
|
||||
}
|
||||
var expiresAt *int64
|
||||
if v, ok := input["expiresAt"]; ok && v != nil {
|
||||
if n, ok := v.(float64); ok && n > 0 {
|
||||
e := int64(n)
|
||||
expiresAt = &e
|
||||
}
|
||||
} else if v, ok := input["expiresIn"]; ok && v != nil {
|
||||
if n, ok := v.(float64); ok && n > 0 {
|
||||
e := time.Now().UnixMilli() + int64(n)*1000
|
||||
expiresAt = &e
|
||||
}
|
||||
}
|
||||
grant, token, err := d.GrantRepo.Create(resourceType, resourceId, target, expiresAt)
|
||||
if err != nil {
|
||||
return failed(c, "Failed to create share", 500)
|
||||
}
|
||||
// Build download URL
|
||||
path := "/download/" + resourceType + "/" + resourceId
|
||||
if target != "" {
|
||||
path += "/" + target
|
||||
}
|
||||
url := getPublicBaseUrl(c) + path + "?token=" + token
|
||||
return success(c, fiber.Map{
|
||||
"id": grant.ID,
|
||||
"resourceType": grant.ResourceType,
|
||||
"resourceId": grant.ResourceId,
|
||||
"target": grant.Target,
|
||||
"expiresAt": grant.ExpiresAt,
|
||||
"enabled": grant.Enabled,
|
||||
"createdAt": grant.CreatedAt,
|
||||
"updatedAt": grant.UpdatedAt,
|
||||
"token": token,
|
||||
"url": url,
|
||||
})
|
||||
}
|
||||
|
||||
func (d *Deps) HandleUpdateShare(c fiber.Ctx) error {
|
||||
id := c.Params("id")
|
||||
var input map[string]any
|
||||
if err := json.Unmarshal(c.Body(), &input); err != nil {
|
||||
return failed(c, "Invalid JSON", 400)
|
||||
}
|
||||
var enabled *bool
|
||||
if v, ok := input["enabled"].(bool); ok {
|
||||
enabled = &v
|
||||
}
|
||||
var expiresAt *int64
|
||||
if v, ok := input["expiresAt"]; ok {
|
||||
if v == nil {
|
||||
expiresAt = new(int64) // 0 means nil
|
||||
} else if n, ok := v.(float64); ok {
|
||||
e := int64(n)
|
||||
expiresAt = &e
|
||||
}
|
||||
}
|
||||
updated, err := d.GrantRepo.Update(id, enabled, expiresAt)
|
||||
if err != nil || updated == nil {
|
||||
return failed(c, "Share not found", 404)
|
||||
}
|
||||
return success(c, updated)
|
||||
}
|
||||
|
||||
func (d *Deps) HandleDeleteShare(c fiber.Ctx) error {
|
||||
id := c.Params("id")
|
||||
snapshot, err := d.GrantRepo.GetSnapshot(id)
|
||||
if err != nil || snapshot == nil {
|
||||
return failed(c, "Share not found", 404)
|
||||
}
|
||||
_, err = d.RecycleRepo.ArchiveAndDelete("share", id, snapshot, "DELETE FROM download_grants WHERE id = ?", id)
|
||||
if err != nil {
|
||||
return failed(c, "Failed to delete share", 500)
|
||||
}
|
||||
return success(c, fiber.Map{"deleted": true})
|
||||
}
|
||||
|
||||
// --- Recycle bin handlers ---
|
||||
|
||||
func (d *Deps) HandleListRecycleBin(c fiber.Ctx) error {
|
||||
@@ -179,13 +59,6 @@ func (d *Deps) HandleRestoreRecycleBinEntry(c fiber.Ctx) error {
|
||||
return failed(c, "Template id already exists", 409)
|
||||
}
|
||||
d.TemplateRepo.Upsert(mapToTemplateRecord(snapshot))
|
||||
case "share":
|
||||
existing, _ := d.GrantRepo.Get(resourceId)
|
||||
if existing != nil {
|
||||
return failed(c, "Share id already exists", 409)
|
||||
}
|
||||
// review-resolution #38: restore tokenHash
|
||||
d.GrantRepo.RestoreFromSnapshot(snapshot)
|
||||
}
|
||||
d.RecycleRepo.Delete(id)
|
||||
return success(c, fiber.Map{
|
||||
@@ -214,7 +87,7 @@ func getPublicBaseUrl(c fiber.Ctx) string {
|
||||
if proto == "" {
|
||||
proto = "http"
|
||||
}
|
||||
return proto + "://" + c.Hostname()
|
||||
return proto + "://" + c.Host()
|
||||
}
|
||||
|
||||
// SetSafeResponseHeader wraps middleware.SetSafeResponseHeader for handler use.
|
||||
|
||||
Reference in New Issue
Block a user