mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-04-19 21:42:24 +00:00
[feature] fallback link calculation
Co-Authored-By: Alireza Ahmadi <alireza7@gmail.com>
This commit is contained in:
parent
c38e1e0cfe
commit
47ccc7b501
4 changed files with 57 additions and 10 deletions
|
@ -38,6 +38,21 @@ func (s *SubService) GetSubs(subId string, host string) ([]string, []string, err
|
||||||
if clients == nil {
|
if clients == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if len(inbound.Listen) > 0 && inbound.Listen[0] == '@' {
|
||||||
|
fallbackMaster, err := s.getFallbackMaster(inbound.Listen)
|
||||||
|
if err == nil {
|
||||||
|
inbound.Listen = fallbackMaster.Listen
|
||||||
|
inbound.Port = fallbackMaster.Port
|
||||||
|
var stream map[string]interface{}
|
||||||
|
json.Unmarshal([]byte(inbound.StreamSettings), &stream)
|
||||||
|
var masterStream map[string]interface{}
|
||||||
|
json.Unmarshal([]byte(fallbackMaster.StreamSettings), &masterStream)
|
||||||
|
stream["security"] = masterStream["security"]
|
||||||
|
stream["tlsSettings"] = masterStream["tlsSettings"]
|
||||||
|
modifiedStream, _ := json.MarshalIndent(stream, "", " ")
|
||||||
|
inbound.StreamSettings = string(modifiedStream)
|
||||||
|
}
|
||||||
|
}
|
||||||
for _, client := range clients {
|
for _, client := range clients {
|
||||||
if client.Enable && client.SubID == subId {
|
if client.Enable && client.SubID == subId {
|
||||||
link := s.getLink(inbound, client.Email)
|
link := s.getLink(inbound, client.Email)
|
||||||
|
@ -93,6 +108,19 @@ func (s *SubService) getClientTraffics(traffics []xray.ClientTraffic, email stri
|
||||||
return xray.ClientTraffic{}
|
return xray.ClientTraffic{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SubService) getFallbackMaster(dest string) (*model.Inbound, error) {
|
||||||
|
db := database.GetDB()
|
||||||
|
var inbound *model.Inbound
|
||||||
|
err := db.Model(model.Inbound{}).
|
||||||
|
Where("JSON_TYPE(settings, '$.fallbacks') = 'array'").
|
||||||
|
Where("EXISTS (SELECT * FROM json_each(settings, '$.fallbacks') WHERE json_extract(value, '$.dest') = ?)", dest).
|
||||||
|
Find(&inbound).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return inbound, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *SubService) getLink(inbound *model.Inbound, email string) string {
|
func (s *SubService) getLink(inbound *model.Inbound, email string) string {
|
||||||
switch inbound.Protocol {
|
switch inbound.Protocol {
|
||||||
case "vmess":
|
case "vmess":
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
this.client = settings.clients[clientIndex];
|
this.client = settings.clients[clientIndex];
|
||||||
remark = this.dbInbound.remark + "-" + this.client.email;
|
remark = this.dbInbound.remark + "-" + this.client.email;
|
||||||
address = this.dbInbound.address;
|
address = this.dbInbound.address;
|
||||||
|
this.subId = '';
|
||||||
this.qrcodes = [];
|
this.qrcodes = [];
|
||||||
if (this.inbound.tls && !ObjectUtil.isArrEmpty(this.inbound.stream.tls.settings.domains)) {
|
if (this.inbound.tls && !ObjectUtil.isArrEmpty(this.inbound.stream.tls.settings.domains)) {
|
||||||
this.inbound.stream.tls.settings.domains.forEach((domain) => {
|
this.inbound.stream.tls.settings.domains.forEach((domain) => {
|
||||||
|
|
|
@ -361,6 +361,7 @@
|
||||||
this.refreshing = true;
|
this.refreshing = true;
|
||||||
const msg = await HttpUtil.post('/panel/inbound/list');
|
const msg = await HttpUtil.post('/panel/inbound/list');
|
||||||
if (!msg.success) {
|
if (!msg.success) {
|
||||||
|
this.refreshing = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.setInbounds(msg.obj);
|
this.setInbounds(msg.obj);
|
||||||
|
@ -763,11 +764,32 @@
|
||||||
default: return client.id;
|
default: return client.id;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
checkFallback(dbInbound) {
|
||||||
|
newDbInbound = new DBInbound(dbInbound);
|
||||||
|
if (dbInbound.listen.startsWith("@")){
|
||||||
|
rootInbound = this.inbounds.find((i) =>
|
||||||
|
i.tls &&
|
||||||
|
['trojan','vless'].includes(i.protocol) &&
|
||||||
|
i.settings.fallbacks.find(f => f.dest === dbInbound.listen)
|
||||||
|
);
|
||||||
|
if (rootInbound) {
|
||||||
|
newDbInbound.listen = rootInbound.listen;
|
||||||
|
newDbInbound.port = rootInbound.port;
|
||||||
|
newInbound = newDbInbound.toInbound();
|
||||||
|
newInbound.stream.security = 'tls';
|
||||||
|
newInbound.stream.tls = rootInbound.stream.tls;
|
||||||
|
newDbInbound.streamSettings = newInbound.stream.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newDbInbound;
|
||||||
|
},
|
||||||
showQrcode(dbInbound, clientIndex) {
|
showQrcode(dbInbound, clientIndex) {
|
||||||
qrModal.show('{{ i18n "qrCode"}}', dbInbound, clientIndex);
|
newDbInbound = this.checkFallback(dbInbound);
|
||||||
|
qrModal.show('{{ i18n "qrCode"}}', newDbInbound, clientIndex);
|
||||||
},
|
},
|
||||||
showInfo(dbInbound, index) {
|
showInfo(dbInbound, index) {
|
||||||
infoModal.show(dbInbound, index);
|
newDbInbound = this.checkFallback(dbInbound);
|
||||||
|
infoModal.show(newDbInbound, index);
|
||||||
},
|
},
|
||||||
switchEnable(dbInboundId) {
|
switchEnable(dbInboundId) {
|
||||||
dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
|
dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
|
||||||
|
@ -868,7 +890,8 @@
|
||||||
},
|
},
|
||||||
inboundLinks(dbInboundId) {
|
inboundLinks(dbInboundId) {
|
||||||
dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
|
dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
|
||||||
txtModal.show('{{ i18n "pages.inbounds.export"}}', dbInbound.genInboundLinks, dbInbound.remark);
|
newDbInbound = this.checkFallback(dbInbound);
|
||||||
|
txtModal.show('{{ i18n "pages.inbounds.export"}}', newDbInbound.genInboundLinks, newDbInbound.remark);
|
||||||
},
|
},
|
||||||
exportAllLinks() {
|
exportAllLinks() {
|
||||||
let copyText = '';
|
let copyText = '';
|
||||||
|
|
9
x-ui.sh
9
x-ui.sh
|
@ -528,6 +528,7 @@ ssl_cert_issue_main() {
|
||||||
local domain=""
|
local domain=""
|
||||||
read -p "Please enter your domain name to revoke the certificate: " domain
|
read -p "Please enter your domain name to revoke the certificate: " domain
|
||||||
~/.acme.sh/acme.sh --revoke -d ${domain}
|
~/.acme.sh/acme.sh --revoke -d ${domain}
|
||||||
|
LOGI "Certificate revoked"
|
||||||
;;
|
;;
|
||||||
3)
|
3)
|
||||||
local domain=""
|
local domain=""
|
||||||
|
@ -571,13 +572,7 @@ ssl_cert_issue() {
|
||||||
local certInfo=$(~/.acme.sh/acme.sh --list)
|
local certInfo=$(~/.acme.sh/acme.sh --list)
|
||||||
LOGE "system already has certs here,can not issue again,current certs details:"
|
LOGE "system already has certs here,can not issue again,current certs details:"
|
||||||
LOGI "$certInfo"
|
LOGI "$certInfo"
|
||||||
read -p "Do you want to revoke the existing certificate? (yes/no): " choice
|
exit 1
|
||||||
if [ "$choice" == "yes" ]; then
|
|
||||||
~/.acme.sh/acme.sh --revoke -d ${domain}
|
|
||||||
LOGI "Certificate revoked"
|
|
||||||
else
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
else
|
else
|
||||||
LOGI "your domain is ready for issuing cert now..."
|
LOGI "your domain is ready for issuing cert now..."
|
||||||
fi
|
fi
|
||||||
|
|
Loading…
Reference in a new issue