108 lines
2.8 KiB
Go
108 lines
2.8 KiB
Go
package router
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
|
|
"github.com/gofiber/fiber/v3"
|
|
|
|
"goimgApi/accounts"
|
|
"goimgApi/images"
|
|
)
|
|
|
|
func SetupRoutes(app *fiber.App) {
|
|
app.Get("/", func(c fiber.Ctx) error {
|
|
return c.SendString("Go Image API Running")
|
|
})
|
|
|
|
app.Get("/uploads/*", func(c fiber.Ctx) error {
|
|
relPath := strings.TrimPrefix(c.Params("*"), "/")
|
|
if relPath == "" {
|
|
return fiber.ErrNotFound
|
|
}
|
|
|
|
cleanPath := filepath.Clean(relPath)
|
|
if cleanPath == "." || strings.HasPrefix(cleanPath, "..") {
|
|
return fiber.ErrForbidden
|
|
}
|
|
|
|
return c.SendFile(filepath.Join("uploads", cleanPath))
|
|
})
|
|
|
|
// Swagger setup
|
|
app.Get("/docs/swagger.json", func(c fiber.Ctx) error {
|
|
raw, err := loadSwaggerSpec()
|
|
if err != nil {
|
|
return fiber.NewError(fiber.StatusInternalServerError, "Swagger spec could not be loaded")
|
|
}
|
|
|
|
var spec map[string]any
|
|
if err := json.Unmarshal(raw, &spec); err != nil {
|
|
return fiber.NewError(fiber.StatusInternalServerError, "Swagger spec is invalid")
|
|
}
|
|
|
|
delete(spec, "host")
|
|
delete(spec, "schemes")
|
|
|
|
return c.JSON(spec)
|
|
})
|
|
app.Get("/swagger", func(c fiber.Ctx) error {
|
|
c.Set("Content-Type", "text/html")
|
|
return c.SendString(`<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>Swagger UI</title>
|
|
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5.3.0/swagger-ui.css" />
|
|
</head>
|
|
<body style="margin:0;">
|
|
<div id="swagger-ui"></div>
|
|
<script src="https://unpkg.com/swagger-ui-dist@5.3.0/swagger-ui-bundle.js"></script>
|
|
<script>
|
|
window.onload = () => {
|
|
window.ui = SwaggerUIBundle({
|
|
url: '/docs/swagger.json',
|
|
dom_id: '#swagger-ui',
|
|
});
|
|
};
|
|
</script>
|
|
</body>
|
|
</html>`)
|
|
})
|
|
|
|
authGroup := app.Group("/auth")
|
|
authGroup.Post("/register", accounts.Register)
|
|
authGroup.Post("/login", accounts.Login)
|
|
authGroup.Post("/refresh", accounts.Refresh)
|
|
|
|
adminGroup := app.Group("/admin", accounts.JWTMiddleware, accounts.AdminMiddleware)
|
|
adminGroup.Post("/users/:id/api-token", accounts.CreateApiToken)
|
|
adminGroup.Get("/images", images.AdminListImages)
|
|
|
|
imagesGroup := app.Group("/images", accounts.JWTMiddleware)
|
|
imagesGroup.Post("/", images.Upload)
|
|
imagesGroup.Get("/", images.ListImages)
|
|
imagesGroup.Get("/:id", images.GetImage)
|
|
|
|
// Process endpoint uses API token authentication (not JWT); keep it outside the JWT group
|
|
app.Get("/images/:id/process", images.Process)
|
|
}
|
|
|
|
func loadSwaggerSpec() ([]byte, error) {
|
|
if raw, err := os.ReadFile("./docs/swagger.json"); err == nil {
|
|
return raw, nil
|
|
}
|
|
|
|
_, currentFile, _, ok := runtime.Caller(0)
|
|
if !ok {
|
|
return nil, os.ErrNotExist
|
|
}
|
|
|
|
projectRoot := filepath.Dir(filepath.Dir(currentFile))
|
|
return os.ReadFile(filepath.Join(projectRoot, "docs", "swagger.json"))
|
|
}
|