Some checks are pending
Release Binaries / Build and Release (.exe, amd64, windows, windows-amd64) (push) Waiting to run
Release Binaries / Build and Release (amd64, darwin, darwin-amd64) (push) Waiting to run
Release Binaries / Build and Release (amd64, linux, linux-amd64) (push) Waiting to run
Release Binaries / Build and Release (arm64, darwin, darwin-arm64) (push) Waiting to run
Release Binaries / Build and Release (arm64, linux, linux-arm64) (push) Waiting to run
- Add Token GORM model with UserID/Name/Token/LastUsedAt/ExpiresAt fields
- Add TokenManager controller: List/Create/Delete/Verify operations
- Add token HTTP handlers: list, create, revoke
- Update AuthVerify to support Bearer token auth; API tokens use "ust_" prefix to distinguish from session tokens
- Add one-step file upload endpoint: PUT /api/v1/upload/:filename (returns {"status":200,"data":{"code":"..."}})
- Add token management routes: GET/POST/DELETE /api/token
- Add /self page: personal center with account info, token management table, and curl usage guide
- Add "个人中心 / API Token" nav link for users with token_manage permission
🤖 Generated with [Qoder][https://qoder.com]
86 lines
2.3 KiB
Go
86 lines
2.3 KiB
Go
package handler
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/loveuer/nf"
|
|
"github.com/loveuer/ushare/internal/controller"
|
|
"github.com/loveuer/ushare/internal/model"
|
|
)
|
|
|
|
func TokenList() nf.HandlerFunc {
|
|
return func(c *nf.Ctx) error {
|
|
session, ok := c.Locals("user").(*model.Session)
|
|
if !ok || session == nil {
|
|
return c.Status(http.StatusUnauthorized).JSON(map[string]string{"error": "unauthorized"})
|
|
}
|
|
|
|
tokens, err := controller.TokenManager.List(session.UserID)
|
|
if err != nil {
|
|
return c.Status(http.StatusInternalServerError).JSON(map[string]string{"msg": err.Error()})
|
|
}
|
|
|
|
return c.Status(http.StatusOK).JSON(map[string]any{"data": tokens})
|
|
}
|
|
}
|
|
|
|
func TokenCreate() nf.HandlerFunc {
|
|
return func(c *nf.Ctx) error {
|
|
session, ok := c.Locals("user").(*model.Session)
|
|
if !ok || session == nil {
|
|
return c.Status(http.StatusUnauthorized).JSON(map[string]string{"error": "unauthorized"})
|
|
}
|
|
|
|
type Req struct {
|
|
Name string `json:"name"`
|
|
}
|
|
|
|
var req Req
|
|
if err := c.BodyParser(&req); err != nil {
|
|
return c.Status(http.StatusBadRequest).JSON(map[string]string{"msg": "请求格式错误"})
|
|
}
|
|
|
|
t, rawToken, err := controller.TokenManager.Create(session.UserID, req.Name)
|
|
if err != nil {
|
|
return c.Status(http.StatusBadRequest).JSON(map[string]string{"msg": err.Error()})
|
|
}
|
|
|
|
return c.Status(http.StatusOK).JSON(map[string]any{
|
|
"data": map[string]any{
|
|
"id": t.ID,
|
|
"name": t.Name,
|
|
"token": rawToken,
|
|
"created_at": t.CreatedAt,
|
|
},
|
|
})
|
|
}
|
|
}
|
|
|
|
func TokenDelete() nf.HandlerFunc {
|
|
return func(c *nf.Ctx) error {
|
|
session, ok := c.Locals("user").(*model.Session)
|
|
if !ok || session == nil {
|
|
return c.Status(http.StatusUnauthorized).JSON(map[string]string{"error": "unauthorized"})
|
|
}
|
|
|
|
type Req struct {
|
|
ID uint `json:"id"`
|
|
}
|
|
|
|
var req Req
|
|
if err := c.BodyParser(&req); err != nil {
|
|
return c.Status(http.StatusBadRequest).JSON(map[string]string{"msg": "请求格式错误"})
|
|
}
|
|
|
|
if req.ID == 0 {
|
|
return c.Status(http.StatusBadRequest).JSON(map[string]string{"msg": "token id 不能为空"})
|
|
}
|
|
|
|
if err := controller.TokenManager.Delete(session.UserID, req.ID); err != nil {
|
|
return c.Status(http.StatusBadRequest).JSON(map[string]string{"msg": err.Error()})
|
|
}
|
|
|
|
return c.Status(http.StatusOK).JSON(map[string]any{"data": "ok"})
|
|
}
|
|
}
|