[api] add server endpoint #1590

This commit is contained in:
Alireza Ahmadi
2025-09-17 23:23:16 +02:00
parent 430ade7952
commit d7fd3e2109
6 changed files with 83 additions and 23 deletions

View File

@@ -209,7 +209,6 @@ docker build -t x-ui .
| :----: | --------------------------------- | ----------------------------------------- | | :----: | --------------------------------- | ----------------------------------------- |
| `GET` | `"/"` | Get all inbounds | | `GET` | `"/"` | Get all inbounds |
| `GET` | `"/get/:id"` | Get inbound with inbound.id | | `GET` | `"/get/:id"` | Get inbound with inbound.id |
| `GET` | `"/createbackup"` | Telegram bot sends backup to admins |
| `POST` | `"/add"` | Add inbound | | `POST` | `"/add"` | Add inbound |
| `POST` | `"/del/:id"` | Delete inbound | | `POST` | `"/del/:id"` | Delete inbound |
| `POST` | `"/update/:id"` | Update inbound | | `POST` | `"/update/:id"` | Update inbound |
@@ -224,11 +223,33 @@ docker build -t x-ui .
| `POST` | `"/delDepletedClients/:id"` | Delete inbound depleted clients (-1: all) | | `POST` | `"/delDepletedClients/:id"` | Delete inbound depleted clients (-1: all) |
| `POST` | `"/onlines"` | Get online users ( list of emails ) | | `POST` | `"/onlines"` | Get online users ( list of emails ) |
\*- The field `clientId` should be filled by: \*- The field `clientId` should be filled by:
- `client.id` for VMess and VLESS - `client.id` for VMess and VLESS
- `client.password` for Trojan - `client.password` for Trojan
- `client.email` for Shadowsocks - `client.email` for Shadowsocks
- `/xui/API/server` base for following actions:
| Method | Path | Action |
| :----: | --------------------------------- | ----------------------------------------- |
| `GET` | `"/status"` | Get server status |
| `GET` | `"/getDb"` | Get database backup |
| `GET` | `"/createbackup"` | Telegram bot sends backup to admins |
| `GET` | `"/getConfigJson"` | Get config.json |
| `GET` | `"/getXrayVersion"` | Get last xray versions |
| `GET` | `"/getNewVlessEnc"` | Get new vless enc |
| `GET` | `"/getNewX25519Cert"` | Get new x25519 cert |
| `GET` | `"/getNewmldsa65"` | Get new mldsa65 |
| `POST` | `"/getNewEchCert"` | Get new ech cert |
| `POST` | `"/importDB"` | Import database to x-ui |
| `POST` | `"/stopXrayService"` | Stop xray service |
| `POST` | `"/restartXrayService"` | Restart xray service |
| `POST` | `"/installXray/:version"` | Install specific version of xray |
| `POST` | `"/logs/:count"` | Get panel/xray logs |
</details> </details>

View File

@@ -9,27 +9,36 @@ import (
type APIController struct { type APIController struct {
BaseController BaseController
inboundController *InboundController inboundController *InboundController
serverController *ServerController
Tgbot service.Tgbot Tgbot service.Tgbot
} }
func NewAPIController(g *gin.RouterGroup) *APIController { func NewAPIController(g *gin.RouterGroup, s *ServerController) *APIController {
a := &APIController{} a := &APIController{
serverController: s,
}
a.initRouter(g) a.initRouter(g)
return a return a
} }
func (a *APIController) initRouter(g *gin.RouterGroup) { func (a *APIController) initRouter(g *gin.RouterGroup) {
g = g.Group("/xui/API/inbounds") api := g.Group("/xui/API")
g.Use(a.checkLogin) api.Use(a.checkLogin)
a.inboundController = NewInboundController(g) a.inboundApi(api)
a.serverApi(api)
}
func (a *APIController) inboundApi(api *gin.RouterGroup) {
inboundsApi := api.Group("/inbounds")
a.inboundController = &InboundController{}
inboundRoutes := []struct { inboundRoutes := []struct {
Method string Method string
Path string Path string
Handler gin.HandlerFunc Handler gin.HandlerFunc
}{ }{
{"GET", "/createbackup", a.createBackup},
{"GET", "/", a.inboundController.getInbounds}, {"GET", "/", a.inboundController.getInbounds},
{"GET", "/get/:id", a.inboundController.getInbound}, {"GET", "/get/:id", a.inboundController.getInbound},
{"GET", "/getClientTraffics/:email", a.inboundController.getClientTraffics}, {"GET", "/getClientTraffics/:email", a.inboundController.getClientTraffics},
@@ -48,7 +57,37 @@ func (a *APIController) initRouter(g *gin.RouterGroup) {
} }
for _, route := range inboundRoutes { for _, route := range inboundRoutes {
g.Handle(route.Method, route.Path, route.Handler) inboundsApi.Handle(route.Method, route.Path, route.Handler)
}
}
func (a *APIController) serverApi(api *gin.RouterGroup) {
serverApi := api.Group("/server")
serverRoutes := []struct {
Method string
Path string
Handler gin.HandlerFunc
}{
{"GET", "/status", a.serverController.status},
{"GET", "/getDb", a.serverController.getDb},
{"GET", "/createbackup", a.createBackup},
{"GET", "/getConfigJson", a.serverController.getConfigJson},
{"GET", "/getXrayVersion", a.serverController.getXrayVersion},
{"GET", "/getNewVlessEnc", a.serverController.getNewVlessEnc},
{"GET", "/getNewX25519Cert", a.serverController.getNewX25519Cert},
{"GET", "/getNewmldsa65", a.serverController.getNewmldsa65},
{"POST", "/getNewEchCert", a.serverController.getNewEchCert},
{"POST", "/importDB", a.serverController.importDB},
{"POST", "/stopXrayService", a.serverController.stopXrayService},
{"POST", "/restartXrayService", a.serverController.restartXrayService},
{"POST", "/installXray/:version", a.serverController.installXray},
{"POST", "/logs/:count", a.serverController.getLogs},
}
for _, route := range serverRoutes {
serverApi.Handle(route.Method, route.Path, route.Handler)
} }
} }

View File

@@ -39,20 +39,20 @@ func (a *ServerController) initRouter(g *gin.RouterGroup) {
g = g.Group("/server") g = g.Group("/server")
g.Use(a.checkLogin) g.Use(a.checkLogin)
g.GET("/status", a.status)
g.GET("/getDb", a.getDb) g.GET("/getDb", a.getDb)
g.GET("/getConfigJson", a.getConfigJson)
g.GET("/getNewmldsa65", a.getNewmldsa65)
g.GET("/getNewVlessEnc", a.getNewVlessEnc) g.GET("/getNewVlessEnc", a.getNewVlessEnc)
g.GET("/getXrayVersion", a.getXrayVersion)
g.GET("/getNewX25519Cert", a.getNewX25519Cert)
g.POST("/status", a.status) g.POST("/getNewEchCert", a.getNewEchCert)
g.POST("/getXrayVersion", a.getXrayVersion)
g.POST("/stopXrayService", a.stopXrayService) g.POST("/stopXrayService", a.stopXrayService)
g.POST("/restartXrayService", a.restartXrayService) g.POST("/restartXrayService", a.restartXrayService)
g.POST("/installXray/:version", a.installXray) g.POST("/installXray/:version", a.installXray)
g.POST("/logs/:count", a.getLogs) g.POST("/logs/:count", a.getLogs)
g.POST("/getConfigJson", a.getConfigJson)
g.POST("/importDB", a.importDB) g.POST("/importDB", a.importDB)
g.POST("/getNewX25519Cert", a.getNewX25519Cert)
g.POST("/getNewmldsa65", a.getNewmldsa65)
g.POST("/getNewEchCert", a.getNewEchCert)
} }
func (a *ServerController) refreshStatus() { func (a *ServerController) refreshStatus() {

View File

@@ -124,7 +124,7 @@
}, },
async getNewX25519Cert(){ async getNewX25519Cert(){
inModal.loading(true); inModal.loading(true);
const msg = await HttpUtil.post('/server/getNewX25519Cert'); const msg = await HttpUtil.get('/server/getNewX25519Cert');
inModal.loading(false); inModal.loading(false);
if (!msg.success) { if (!msg.success) {
return; return;
@@ -138,7 +138,7 @@
}, },
async getNewmldsa65() { async getNewmldsa65() {
inModal.loading(true); inModal.loading(true);
const msg = await HttpUtil.post('/server/getNewmldsa65'); const msg = await HttpUtil.get('/server/getNewmldsa65');
inModal.loading(false); inModal.loading(false);
if (!msg.success) { if (!msg.success) {
return; return;

View File

@@ -535,7 +535,7 @@
this.loadingTip = tip; this.loadingTip = tip;
}, },
async getStatus() { async getStatus() {
const msg = await HttpUtil.post('/server/status'); const msg = await HttpUtil.get('/server/status');
if (msg.success) { if (msg.success) {
this.setStatus(msg.obj); this.setStatus(msg.obj);
} }
@@ -545,7 +545,7 @@
}, },
async openSelectV2rayVersion() { async openSelectV2rayVersion() {
this.loading(true); this.loading(true);
const msg = await HttpUtil.post('server/getXrayVersion'); const msg = await HttpUtil.get('server/getXrayVersion');
this.loading(false); this.loading(false);
if (!msg.success) { if (!msg.success) {
return; return;
@@ -595,7 +595,7 @@
}, },
async openConfig() { async openConfig() {
this.loading(true); this.loading(true);
const msg = await HttpUtil.post('server/getConfigJson'); const msg = await HttpUtil.get('server/getConfigJson');
this.loading(false); this.loading(false);
if (!msg.success) { if (!msg.success) {
return; return;

View File

@@ -228,7 +228,7 @@ func (s *Server) initRouter() (*gin.Engine, error) {
s.index = controller.NewIndexController(g) s.index = controller.NewIndexController(g)
s.server = controller.NewServerController(g) s.server = controller.NewServerController(g)
s.xui = controller.NewXUIController(g) s.xui = controller.NewXUIController(g)
s.api = controller.NewAPIController(g) s.api = controller.NewAPIController(g, s.server)
return engine, nil return engine, nil
} }