mirror of
https://gitee.com/wanwujie/sub2api
synced 2026-04-03 06:52:13 +08:00
Add a system-wide "Backend Mode" that disables user self-registration and self-service while keeping admin panel and API gateway fully functional. When enabled, only admin can log in; all user-facing routes return 403. Backend: - New setting key `backend_mode_enabled` with atomic cached reads (60s TTL) - BackendModeUserGuard middleware blocks non-admin authenticated routes - BackendModeAuthGuard middleware blocks registration/password-reset auth routes - Login/Login2FA/RefreshToken handlers reject non-admin when enabled - TokenPairWithUser struct for role-aware token refresh - 20 unit tests (middleware + service layer) Frontend: - Router guards redirect unauthenticated users to /login - Admin toggle in Settings page - Login page hides register link and footer in backend mode - 9 unit tests for router guard logic - i18n support (en/zh) 27 files changed, 833 insertions(+), 17 deletions(-) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
95 lines
2.6 KiB
Go
95 lines
2.6 KiB
Go
package routes
|
|
|
|
import (
|
|
"github.com/Wei-Shaw/sub2api/internal/handler"
|
|
"github.com/Wei-Shaw/sub2api/internal/server/middleware"
|
|
"github.com/Wei-Shaw/sub2api/internal/service"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// RegisterUserRoutes 注册用户相关路由(需要认证)
|
|
func RegisterUserRoutes(
|
|
v1 *gin.RouterGroup,
|
|
h *handler.Handlers,
|
|
jwtAuth middleware.JWTAuthMiddleware,
|
|
settingService *service.SettingService,
|
|
) {
|
|
authenticated := v1.Group("")
|
|
authenticated.Use(gin.HandlerFunc(jwtAuth))
|
|
authenticated.Use(middleware.BackendModeUserGuard(settingService))
|
|
{
|
|
// 用户接口
|
|
user := authenticated.Group("/user")
|
|
{
|
|
user.GET("/profile", h.User.GetProfile)
|
|
user.PUT("/password", h.User.ChangePassword)
|
|
user.PUT("", h.User.UpdateProfile)
|
|
|
|
// TOTP 双因素认证
|
|
totp := user.Group("/totp")
|
|
{
|
|
totp.GET("/status", h.Totp.GetStatus)
|
|
totp.GET("/verification-method", h.Totp.GetVerificationMethod)
|
|
totp.POST("/send-code", h.Totp.SendVerifyCode)
|
|
totp.POST("/setup", h.Totp.InitiateSetup)
|
|
totp.POST("/enable", h.Totp.Enable)
|
|
totp.POST("/disable", h.Totp.Disable)
|
|
}
|
|
}
|
|
|
|
// API Key管理
|
|
keys := authenticated.Group("/keys")
|
|
{
|
|
keys.GET("", h.APIKey.List)
|
|
keys.GET("/:id", h.APIKey.GetByID)
|
|
keys.POST("", h.APIKey.Create)
|
|
keys.PUT("/:id", h.APIKey.Update)
|
|
keys.DELETE("/:id", h.APIKey.Delete)
|
|
}
|
|
|
|
// 用户可用分组(非管理员接口)
|
|
groups := authenticated.Group("/groups")
|
|
{
|
|
groups.GET("/available", h.APIKey.GetAvailableGroups)
|
|
groups.GET("/rates", h.APIKey.GetUserGroupRates)
|
|
}
|
|
|
|
// 使用记录
|
|
usage := authenticated.Group("/usage")
|
|
{
|
|
usage.GET("", h.Usage.List)
|
|
usage.GET("/:id", h.Usage.GetByID)
|
|
usage.GET("/stats", h.Usage.Stats)
|
|
// User dashboard endpoints
|
|
usage.GET("/dashboard/stats", h.Usage.DashboardStats)
|
|
usage.GET("/dashboard/trend", h.Usage.DashboardTrend)
|
|
usage.GET("/dashboard/models", h.Usage.DashboardModels)
|
|
usage.POST("/dashboard/api-keys-usage", h.Usage.DashboardAPIKeysUsage)
|
|
}
|
|
|
|
// 公告(用户可见)
|
|
announcements := authenticated.Group("/announcements")
|
|
{
|
|
announcements.GET("", h.Announcement.List)
|
|
announcements.POST("/:id/read", h.Announcement.MarkRead)
|
|
}
|
|
|
|
// 卡密兑换
|
|
redeem := authenticated.Group("/redeem")
|
|
{
|
|
redeem.POST("", h.Redeem.Redeem)
|
|
redeem.GET("/history", h.Redeem.GetHistory)
|
|
}
|
|
|
|
// 用户订阅
|
|
subscriptions := authenticated.Group("/subscriptions")
|
|
{
|
|
subscriptions.GET("", h.Subscription.List)
|
|
subscriptions.GET("/active", h.Subscription.GetActive)
|
|
subscriptions.GET("/progress", h.Subscription.GetProgress)
|
|
subscriptions.GET("/summary", h.Subscription.GetSummary)
|
|
}
|
|
}
|
|
}
|