mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-06 13:14:11 +00:00
- Update go.mod module path from mhsanaei/3x-ui/v3 to saeederamy/3x-ui/v3 - Update all 73 Go files' import paths accordingly - Fix README.fa_IR.md install command to point to fork's main branch The fork was referencing the original repo's module path in go.mod and all Go source imports, making it dependent on MHSanaei's namespace at build time. https://claude.ai/code/session_01M6d5atbWjuLTj6UwRHoK5m
94 lines
2.9 KiB
Go
94 lines
2.9 KiB
Go
package controller
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/saeederamy/3x-ui/v3/web/middleware"
|
|
"github.com/saeederamy/3x-ui/v3/web/service"
|
|
"github.com/saeederamy/3x-ui/v3/web/session"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// APIController handles the main API routes for the 3x-ui panel, including inbounds and server management.
|
|
type APIController struct {
|
|
BaseController
|
|
inboundController *InboundController
|
|
serverController *ServerController
|
|
nodeController *NodeController
|
|
settingService service.SettingService
|
|
userService service.UserService
|
|
Tgbot service.Tgbot
|
|
}
|
|
|
|
// NewAPIController creates a new APIController instance and initializes its routes.
|
|
func NewAPIController(g *gin.RouterGroup, customGeo *service.CustomGeoService) *APIController {
|
|
a := &APIController{}
|
|
a.initRouter(g, customGeo)
|
|
return a
|
|
}
|
|
|
|
// checkAPIAuth is a middleware that returns 404 for unauthenticated API requests
|
|
// to hide the existence of API endpoints from unauthorized users.
|
|
//
|
|
// Two auth paths are accepted:
|
|
// 1. Authorization: Bearer <apiToken> — used by remote central panels
|
|
// polling this instance as a node. Matches via constant-time compare.
|
|
// Sets c.Set("api_authed", true) so CSRFMiddleware can short-circuit.
|
|
// 2. Existing session cookie — used by browsers logged into the panel UI.
|
|
//
|
|
// Anything else falls through to a 404 so the API endpoints remain hidden.
|
|
func (a *APIController) checkAPIAuth(c *gin.Context) {
|
|
auth := c.GetHeader("Authorization")
|
|
if strings.HasPrefix(auth, "Bearer ") {
|
|
tok := strings.TrimPrefix(auth, "Bearer ")
|
|
if a.settingService.MatchApiToken(tok) {
|
|
// Handlers like InboundController.addInbound assume a logged-in
|
|
// user (inbound.UserId = user.Id). Bearer callers have no
|
|
// session, so attach the first user as a fallback. Single-user
|
|
// panels are the norm here.
|
|
if u, err := a.userService.GetFirstUser(); err == nil {
|
|
session.SetAPIAuthUser(c, u)
|
|
}
|
|
c.Set("api_authed", true)
|
|
c.Next()
|
|
return
|
|
}
|
|
}
|
|
if !session.IsLogin(c) {
|
|
c.AbortWithStatus(http.StatusNotFound)
|
|
return
|
|
}
|
|
c.Next()
|
|
}
|
|
|
|
// initRouter sets up the API routes for inbounds, server, and other endpoints.
|
|
func (a *APIController) initRouter(g *gin.RouterGroup, customGeo *service.CustomGeoService) {
|
|
// Main API group
|
|
api := g.Group("/panel/api")
|
|
api.Use(a.checkAPIAuth)
|
|
api.Use(middleware.CSRFMiddleware())
|
|
|
|
// Inbounds API
|
|
inbounds := api.Group("/inbounds")
|
|
a.inboundController = NewInboundController(inbounds)
|
|
|
|
// Server API
|
|
server := api.Group("/server")
|
|
a.serverController = NewServerController(server)
|
|
|
|
// Nodes API — multi-panel management
|
|
nodes := api.Group("/nodes")
|
|
a.nodeController = NewNodeController(nodes)
|
|
|
|
NewCustomGeoController(api.Group("/custom-geo"), customGeo)
|
|
|
|
// Extra routes
|
|
api.GET("/backuptotgbot", a.BackuptoTgbot)
|
|
}
|
|
|
|
// BackuptoTgbot sends a backup of the panel data to Telegram bot admins.
|
|
func (a *APIController) BackuptoTgbot(c *gin.Context) {
|
|
a.Tgbot.SendBackupToAdmins()
|
|
}
|