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 {