mirror of
https://github.com/alireza0/x-ui.git
synced 2026-03-13 21:13:09 +00:00
[sub] frontend and adaptation
This commit is contained in:
@@ -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"`
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
<a-form-item label='{{ i18n "additional" }} ID' v-if="inbound.protocol === Protocols.VMESS">
|
||||
<a-input type="number" v-model.number="client.alterId"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="Subscription" v-if="client.email">
|
||||
<a-input v-model.trim="client.subId"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item v-if="inbound.xtls" label="flow">
|
||||
<a-select v-model="client.flow" style="width: 150px" :dropdown-class-name="siderDrawer.isDarkTheme ? 'ant-card-dark' : ''">
|
||||
<a-select-option value="">{{ i18n "none" }}</a-select-option>
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user