Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/MHSanaei/3x-ui.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMHSanaei <ho3ein.sanaei@gmail.com>2023-07-18 02:10:22 +0300
committerMHSanaei <ho3ein.sanaei@gmail.com>2023-07-18 02:10:22 +0300
commit1f78842b707a1190b6a84aded269d664254a7f1d (patch)
treef9226bfda4856a6289a657cff21234738be4f8c3 /web/service
parent81a057d63876df5ba69260ac6b97aeeb7964c87d (diff)
[feature] using xray API for inbound
Co-Authored-By: Alireza Ahmadi <alireza7@gmail.com>
Diffstat (limited to 'web/service')
-rw-r--r--web/service/inbound.go167
-rw-r--r--web/service/server.go11
2 files changed, 133 insertions, 45 deletions
diff --git a/web/service/inbound.go b/web/service/inbound.go
index b278eb57..b77b2209 100644
--- a/web/service/inbound.go
+++ b/web/service/inbound.go
@@ -5,7 +5,6 @@ import (
"fmt"
"strings"
"time"
-
"x-ui/database"
"x-ui/database/model"
"x-ui/logger"
@@ -75,6 +74,7 @@ func (s *InboundService) getAllEmails() ([]string, error) {
FROM inbounds,
JSON_EACH(JSON_EXTRACT(inbounds.settings, '$.clients')) AS client
`).Scan(&emails).Error
+
if err != nil {
return nil, err
}
@@ -134,26 +134,26 @@ func (s *InboundService) checkEmailExistForInbound(inbound *model.Inbound) (stri
return "", nil
}
-func (s *InboundService) AddInbound(inbound *model.Inbound) (*model.Inbound, error) {
+func (s *InboundService) AddInbound(inbound *model.Inbound) (*model.Inbound, bool, error) {
exist, err := s.checkPortExist(inbound.Port, 0)
if err != nil {
- return inbound, err
+ return inbound, false, err
}
if exist {
- return inbound, common.NewError("Port already exists:", inbound.Port)
+ return inbound, false, common.NewError("Port already exists:", inbound.Port)
}
existEmail, err := s.checkEmailExistForInbound(inbound)
if err != nil {
- return inbound, err
+ return inbound, false, err
}
if existEmail != "" {
- return inbound, common.NewError("Duplicate email:", existEmail)
+ return inbound, false, common.NewError("Duplicate email:", existEmail)
}
clients, err := s.GetClients(inbound)
if err != nil {
- return inbound, err
+ return inbound, false, err
}
db := database.GetDB()
@@ -172,7 +172,26 @@ func (s *InboundService) AddInbound(inbound *model.Inbound) (*model.Inbound, err
s.AddClientStat(tx, inbound.Id, &client)
}
}
- return inbound, err
+
+ needRestart := false
+ if inbound.Enable {
+ s.xrayApi.Init(p.GetAPIPort())
+ inboundJson, err1 := json.MarshalIndent(inbound.GenXrayInboundConfig(), "", " ")
+ if err1 != nil {
+ logger.Debug("Unable to marshal inbound config:", err1)
+ }
+
+ err1 = s.xrayApi.AddInbound(inboundJson)
+ if err1 == nil {
+ logger.Debug("New inbound added by api:", inbound.Tag)
+ } else {
+ logger.Debug("Unable to add inbound by api:", err1)
+ needRestart = true
+ }
+ s.xrayApi.Close()
+ }
+
+ return inbound, needRestart, err
}
func (s *InboundService) AddInbounds(inbounds []*model.Inbound) error {
@@ -207,27 +226,47 @@ func (s *InboundService) AddInbounds(inbounds []*model.Inbound) error {
return nil
}
-func (s *InboundService) DelInbound(id int) error {
+func (s *InboundService) DelInbound(id int) (bool, error) {
db := database.GetDB()
+
+ var tag string
+ needRestart := false
+ result := db.Model(model.Inbound{}).Select("tag").Where("id = ? and enable = ?", id, true).First(&tag)
+ if result.Error == nil {
+ s.xrayApi.Init(p.GetAPIPort())
+ err1 := s.xrayApi.DelInbound(tag)
+ if err1 == nil {
+ logger.Debug("Inbound deleted by api:", tag)
+ } else {
+ logger.Debug("Unable to delete inbound by api:", err1)
+ needRestart = true
+ }
+ s.xrayApi.Close()
+ } else {
+ logger.Debug("No enabled inbound founded to removing by api", tag)
+ }
+
+ // Delete client traffics of inbounds
err := db.Where("inbound_id = ?", id).Delete(xray.ClientTraffic{}).Error
if err != nil {
- return err
+ return false, err
}
inbound, err := s.GetInbound(id)
if err != nil {
- return err
+ return false, err
}
clients, err := s.GetClients(inbound)
if err != nil {
- return err
+ return false, err
}
for _, client := range clients {
err := s.DelClientIPs(db, client.Email)
if err != nil {
- return err
+ return false, err
}
}
- return db.Delete(model.Inbound{}, id).Error
+
+ return needRestart, db.Delete(model.Inbound{}, id).Error
}
func (s *InboundService) GetInbound(id int) (*model.Inbound, error) {
@@ -240,23 +279,25 @@ func (s *InboundService) GetInbound(id int) (*model.Inbound, error) {
return inbound, nil
}
-func (s *InboundService) UpdateInbound(inbound *model.Inbound) (*model.Inbound, error) {
+func (s *InboundService) UpdateInbound(inbound *model.Inbound) (*model.Inbound, bool, error) {
exist, err := s.checkPortExist(inbound.Port, inbound.Id)
if err != nil {
- return inbound, err
+ return inbound, false, err
}
if exist {
- return inbound, common.NewError("Port already exists:", inbound.Port)
+ return inbound, false, common.NewError("Port already exists:", inbound.Port)
}
oldInbound, err := s.GetInbound(inbound.Id)
if err != nil {
- return inbound, err
+ return inbound, false, err
}
+ tag := oldInbound.Tag
+
err = s.updateClientTraffics(oldInbound, inbound)
if err != nil {
- return inbound, err
+ return inbound, false, err
}
oldInbound.Up = inbound.Up
@@ -273,8 +314,34 @@ func (s *InboundService) UpdateInbound(inbound *model.Inbound) (*model.Inbound,
oldInbound.Sniffing = inbound.Sniffing
oldInbound.Tag = fmt.Sprintf("inbound-%v", inbound.Port)
+ needRestart := false
+ s.xrayApi.Init(p.GetAPIPort())
+ err1 := s.xrayApi.DelInbound(tag)
+ if err1 != nil {
+ logger.Debug("Unable to delete old inbound by api:", err1)
+ needRestart = true
+ } else {
+ logger.Debug("Old inbound deleted by api:", tag)
+
+ if inbound.Enable {
+ inboundJson, err2 := json.MarshalIndent(oldInbound.GenXrayInboundConfig(), "", " ")
+ if err2 != nil {
+ logger.Debug("Unable to marshal updated inbound config:", err2)
+ }
+
+ err2 = s.xrayApi.AddInbound(inboundJson)
+ if err1 == nil {
+ logger.Debug("Updated inbound added by api:", oldInbound.Tag)
+ } else {
+ logger.Debug("Unable to update inbound by api:", err2)
+ needRestart = true
+ }
+ }
+ }
+ s.xrayApi.Close()
+
db := database.GetDB()
- return inbound, db.Save(oldInbound).Error
+ return inbound, needRestart, db.Save(oldInbound).Error
}
func (s *InboundService) updateClientTraffics(oldInbound *model.Inbound, newInbound *model.Inbound) error {
@@ -393,16 +460,18 @@ func (s *InboundService) AddInboundClient(data *model.Inbound) (bool, error) {
for _, client := range clients {
if len(client.Email) > 0 {
s.AddClientStat(tx, data.Id, &client)
- err1 := s.xrayApi.AddUser(string(oldInbound.Protocol), oldInbound.Tag, map[string]interface{}{
- "email": client.Email,
- "id": client.ID,
- "flow": client.Flow,
- "password": client.Password,
- })
- if err1 == nil {
- logger.Debug("Client added by api:", client.Email)
- } else {
- needRestart = true
+ if client.Enable {
+ err1 := s.xrayApi.AddUser(string(oldInbound.Protocol), oldInbound.Tag, map[string]interface{}{
+ "email": client.Email,
+ "id": client.ID,
+ "flow": client.Flow,
+ "password": client.Password,
+ })
+ if err1 == nil {
+ logger.Debug("Client added by api:", client.Email)
+ } else {
+ needRestart = true
+ }
}
} else {
needRestart = true
@@ -466,7 +535,7 @@ func (s *InboundService) DelInboundClient(inboundId int, clientId string) (bool,
logger.Error("Error in delete client IPs")
return false, err
}
- needRestart := true
+ needRestart := false
s.xrayApi.Init(p.GetAPIPort())
if len(email) > 0 {
err = s.xrayApi.RemoveUser(oldInbound.Tag, email)
@@ -580,7 +649,7 @@ func (s *InboundService) UpdateInboundClient(data *model.Inbound, clientId strin
return false, err
}
}
- needRestart := true
+ needRestart := false
s.xrayApi.Init(p.GetAPIPort())
if len(oldEmail) > 0 {
s.xrayApi.RemoveUser(oldInbound.Tag, oldEmail)
@@ -729,15 +798,38 @@ func (s *InboundService) adjustTraffics(tx *gorm.DB, dbClientTraffics []*xray.Cl
return dbClientTraffics, nil
}
-func (s *InboundService) DisableInvalidInbounds() (int64, error) {
+func (s *InboundService) DisableInvalidInbounds() (bool, int64, error) {
db := database.GetDB()
now := time.Now().Unix() * 1000
+ needRestart := false
+
+ if p != nil {
+ var tags []string
+ err := db.Table("inbounds").
+ Select("inbounds.tag").
+ Where("((total > 0 and up + down >= total) or (expiry_time > 0 and expiry_time <= ?)) and enable = ?", now, true).
+ Scan(&tags).Error
+ if err != nil {
+ return false, 0, err
+ }
+ s.xrayApi.Init(p.GetAPIPort())
+ for _, tag := range tags {
+ err = s.xrayApi.DelInbound(tag)
+ if err == nil {
+ logger.Debug("Inbound disabled by api:", tag)
+ } else {
+ needRestart = true
+ }
+ }
+ s.xrayApi.Close()
+ }
+
result := db.Model(model.Inbound{}).
Where("((total > 0 and up + down >= total) or (expiry_time > 0 and expiry_time <= ?)) and enable = ?", now, true).
Update("enable", false)
err := result.Error
count := result.RowsAffected
- return count, err
+ return needRestart, count, err
}
func (s *InboundService) DisableInvalidClients() (bool, int64, error) {
@@ -763,7 +855,7 @@ func (s *InboundService) DisableInvalidClients() (bool, int64, error) {
for _, result := range results {
err = s.xrayApi.RemoveUser(result.Tag, result.Email)
if err == nil {
- logger.Debug("Client deleted by api:", result.Email)
+ logger.Debug("Client disabled by api:", result.Email)
} else {
needRestart = true
}
@@ -816,8 +908,7 @@ func (s *InboundService) UpdateClientStat(email string, client *model.Client) er
"enable": true,
"email": client.Email,
"total": client.TotalGB,
- "expiry_time": client.ExpiryTime,
- })
+ "expiry_time": client.ExpiryTime})
err := result.Error
if err != nil {
return err
@@ -1208,6 +1299,7 @@ func (s *InboundService) ResetAllClientTraffics(id int) error {
Updates(map[string]interface{}{"enable": true, "up": 0, "down": 0})
err := result.Error
+
if err != nil {
return err
}
@@ -1222,6 +1314,7 @@ func (s *InboundService) ResetAllTraffics() error {
Updates(map[string]interface{}{"up": 0, "down": 0})
err := result.Error
+
if err != nil {
return err
}
diff --git a/web/service/server.go b/web/service/server.go
index 5216be5a..c5f4e264 100644
--- a/web/service/server.go
+++ b/web/service/server.go
@@ -403,25 +403,20 @@ func (s *ServerService) GetLogs(count string, logLevel string) ([]string, error)
}
func (s *ServerService) GetConfigJson() (interface{}, error) {
- // Open the file for reading
- file, err := os.Open(xray.GetConfigPath())
+ config, err := s.xrayService.GetXrayConfig()
if err != nil {
return nil, err
}
- defer file.Close()
-
- // Read the file contents
- fileContents, err := io.ReadAll(file)
+ contents, err := json.MarshalIndent(config, "", " ")
if err != nil {
return nil, err
}
var jsonData interface{}
- err = json.Unmarshal(fileContents, &jsonData)
+ err = json.Unmarshal(contents, &jsonData)
if err != nil {
return nil, err
}
-
return jsonData, nil
}