diff --git a/database/model/model.go b/database/model/model.go index d0b8bcfc..e87e8b6b 100644 --- a/database/model/model.go +++ b/database/model/model.go @@ -74,4 +74,5 @@ type Client struct { Email string `json:"email"` TotalGB int64 `json:"totalGB" form:"totalGB"` ExpiryTime int64 `json:"expiryTime" form:"expiryTime"` + SubID string `json:"subId" from:"subId"` } diff --git a/web/assets/js/model/xray.js b/web/assets/js/model/xray.js index ecc9c9d8..6e552d15 100644 --- a/web/assets/js/model/xray.js +++ b/web/assets/js/model/xray.js @@ -1431,13 +1431,14 @@ Inbound.VmessSettings = class extends Inbound.Settings { } }; Inbound.VmessSettings.Vmess = class extends XrayCommonClass { - constructor(id=RandomUtil.randomUUID(), alterId=0, email=RandomUtil.randomText(), totalGB=0, expiryTime=0) { + , subId='') { super(); this.id = id; this.alterId = alterId; this.email = email; this.totalGB = totalGB; this.expiryTime = expiryTime; + this.subId = subId; } static fromJson(json={}) { @@ -1447,7 +1448,7 @@ Inbound.VmessSettings.Vmess = class extends XrayCommonClass { json.email, json.totalGB, json.expiryTime, - + json.subId, ); } get _expiryTime() { @@ -1514,14 +1515,14 @@ Inbound.VLESSSettings = class extends Inbound.Settings { }; Inbound.VLESSSettings.VLESS = class extends XrayCommonClass { - constructor(id=RandomUtil.randomUUID(), flow='', email=RandomUtil.randomText(), totalGB=0, expiryTime=0) { + , subId='') { super(); this.id = id; this.flow = flow; this.email = email; this.totalGB = totalGB; this.expiryTime = expiryTime; - + this.subId = subId; } static fromJson(json={}) { @@ -1531,6 +1532,7 @@ Inbound.VLESSSettings.VLESS = class extends XrayCommonClass { json.email, json.totalGB, json.expiryTime, + json.subId, ); } @@ -1627,13 +1629,14 @@ Inbound.TrojanSettings = class extends Inbound.Settings { } }; Inbound.TrojanSettings.Trojan = class extends XrayCommonClass { - constructor(password=RandomUtil.randomSeq(10), flow='', email=RandomUtil.randomText(), totalGB=0, expiryTime=0) { + , subId='') { super(); this.password = password; this.flow = flow; this.email = email; this.totalGB = totalGB; this.expiryTime = expiryTime; + this.subId = subId; } toJson() { @@ -1643,6 +1646,7 @@ Inbound.TrojanSettings.Trojan = class extends XrayCommonClass { email: this.email, totalGB: this.totalGB, expiryTime: this.expiryTime, + subId: this.subId, }; } @@ -1653,7 +1657,7 @@ Inbound.TrojanSettings.Trojan = class extends XrayCommonClass { json.email, json.totalGB, json.expiryTime, - + json.subId, ); } diff --git a/web/controller/sub.go b/web/controller/sub.go index 61a11836..38340f9b 100644 --- a/web/controller/sub.go +++ b/web/controller/sub.go @@ -1,6 +1,7 @@ package controller import ( + "encoding/base64" "x-ui/web/service" "github.com/gin-gonic/gin" @@ -35,6 +36,6 @@ func (a *SUBController) subs(c *gin.Context) { if err != nil { c.String(400, "Error!") } else { - c.String(200, result) + c.String(200, base64.StdEncoding.EncodeToString([]byte(result))) } } diff --git a/web/html/xui/form/client.html b/web/html/xui/form/client.html index 3d92c54e..fe87734a 100644 --- a/web/html/xui/form/client.html +++ b/web/html/xui/form/client.html @@ -24,6 +24,9 @@ + + + {{ i18n "none" }} diff --git a/web/service/sub.go b/web/service/sub.go index da91f346..875a5b53 100644 --- a/web/service/sub.go +++ b/web/service/sub.go @@ -7,51 +7,50 @@ import ( "strings" "x-ui/database" "x-ui/database/model" - "x-ui/xray" + "x-ui/logger" "github.com/goccy/go-json" "gorm.io/gorm" ) type SubService struct { - address string + address string + inboundService InboundService } func (s *SubService) GetSubs(subId string, host string) ([]string, error) { s.address = host var result []string - traffics, err := s.getTrafficsBySubId(subId) + inbounds, err := s.getInboundsBySubId(subId) if err != nil { return nil, err } - for _, traffic := range traffics { - inbound, err := s.getInbound(traffic.InboundId) + for _, inbound := range inbounds { + clients, err := s.inboundService.getClients(inbound) if err != nil { - return nil, err + logger.Error("SubService - GetSub: Unable to get clients from inbound") + } + if clients == nil { + continue + } + for _, client := range clients { + if client.SubID == subId { + link := s.getLink(inbound, client.Email) + result = append(result, link) + } } - result = append(result, s.getLink(inbound, traffic.Email)) } return result, nil } -func (s *SubService) getTrafficsBySubId(subId string) ([]*xray.ClientTraffic, error) { +func (s *SubService) getInboundsBySubId(subId string) ([]*model.Inbound, error) { db := database.GetDB() - var traffics []*xray.ClientTraffic - err := db.Model(xray.ClientTraffic{}).Where("sub_id = ?", subId).Find(&traffics).Error + var inbounds []*model.Inbound + err := db.Model(model.Inbound{}).Where("settings like ?", fmt.Sprintf(`%%"subId": "%s"%%`, subId)).Find(&inbounds).Error if err != nil && err != gorm.ErrRecordNotFound { return nil, err } - return traffics, nil -} - -func (s *SubService) getInbound(id int) (*model.Inbound, error) { - db := database.GetDB() - inbound := &model.Inbound{} - err := db.Model(model.Inbound{}).First(inbound, id).Error - if err != nil { - return nil, err - } - return inbound, nil + return inbounds, nil } func (s *SubService) getLink(inbound *model.Inbound, email string) string { @@ -144,9 +143,7 @@ func (s *SubService) genVmessLink(inbound *model.Inbound, email string) string { } } - settings := map[string][]model.Client{} - json.Unmarshal([]byte(inbound.Settings), &settings) - clients := settings["clients"] + clients, _ := s.inboundService.getClients(inbound) clientIndex := -1 for i, client := range clients { if client.Email == email { @@ -183,9 +180,7 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string { } var stream map[string]interface{} json.Unmarshal([]byte(inbound.StreamSettings), &stream) - settings := map[string][]model.Client{} - json.Unmarshal([]byte(inbound.Settings), &settings) - clients := settings["clients"] + clients, _ := s.inboundService.getClients(inbound) clientIndex := -1 for i, client := range clients { if client.Email == email { @@ -333,9 +328,7 @@ func (s *SubService) genTrojanLink(inbound *model.Inbound, email string) string } var stream map[string]interface{} json.Unmarshal([]byte(inbound.StreamSettings), &stream) - settings := map[string][]model.Client{} - json.Unmarshal([]byte(inbound.Settings), &settings) - clients := settings["clients"] + clients, _ := s.inboundService.getClients(inbound) clientIndex := -1 for i, client := range clients { if client.Email == email {