diff --git a/web/assets/js/model/dbinbound.js b/web/assets/js/model/dbinbound.js
index a8810899..7f4f0812 100644
--- a/web/assets/js/model/dbinbound.js
+++ b/web/assets/js/model/dbinbound.js
@@ -136,14 +136,9 @@ class DBInbound {
return false;
}
}
-
- genLink(address=this.address, remark=this.remark, clientIndex=0) {
- const inbound = this.toInbound();
- return inbound.genLink(address, remark, clientIndex);
- }
get genInboundLinks() {
const inbound = this.toInbound();
- return inbound.genInboundLinks(this.address, this.remark);
+ return inbound.genInboundLinks(this.remark);
}
}
\ No newline at end of file
diff --git a/web/assets/js/model/xray.js b/web/assets/js/model/xray.js
index fdaeef97..85cd7e5a 100644
--- a/web/assets/js/model/xray.js
+++ b/web/assets/js/model/xray.js
@@ -567,14 +567,12 @@ TlsStreamSettings.Settings = class extends XrayCommonClass {
this.allowInsecure = allowInsecure;
this.fingerprint = fingerprint;
this.serverName = serverName;
- this.domains = domains;
}
static fromJson(json = {}) {
return new TlsStreamSettings.Settings(
json.allowInsecure,
json.fingerprint,
json.serverName,
- json.domains,
);
}
toJson() {
@@ -582,7 +580,6 @@ TlsStreamSettings.Settings = class extends XrayCommonClass {
allowInsecure: this.allowInsecure,
fingerprint: this.fingerprint,
serverName: this.serverName,
- domains: this.domains,
};
}
};
@@ -700,6 +697,7 @@ class SockoptStreamSettings extends XrayCommonClass {
class StreamSettings extends XrayCommonClass {
constructor(network='tcp',
security='none',
+ externalProxy = [],
tlsSettings=new TlsStreamSettings(),
realitySettings = new RealityStreamSettings(),
tcpSettings=new TcpStreamSettings(),
@@ -713,6 +711,7 @@ class StreamSettings extends XrayCommonClass {
super();
this.network = network;
this.security = security;
+ this.externalProxy = externalProxy;
this.tls = tlsSettings;
this.reality = realitySettings;
this.tcp = tcpSettings;
@@ -757,10 +756,10 @@ class StreamSettings extends XrayCommonClass {
}
static fromJson(json={}) {
-
return new StreamSettings(
json.network,
json.security,
+ json.externalProxy,
TlsStreamSettings.fromJson(json.tlsSettings),
RealityStreamSettings.fromJson(json.realitySettings),
TcpStreamSettings.fromJson(json.tcpSettings),
@@ -778,6 +777,7 @@ class StreamSettings extends XrayCommonClass {
return {
network: network,
security: this.security,
+ externalProxy: this.externalProxy,
tlsSettings: this.isTls ? this.tls.toJson() : undefined,
realitySettings: this.isReality ? this.reality.toJson() : undefined,
tcpSettings: network === 'tcp' ? this.tcp.toJson() : undefined,
@@ -836,6 +836,16 @@ class Inbound extends XrayCommonClass {
return this.clientStats;
}
+ get clients() {
+ switch (this.protocol) {
+ case Protocols.VMESS: return this.settings.vmesses;
+ case Protocols.VLESS: return this.settings.vlesses;
+ case Protocols.TROJAN: return this.settings.trojans;
+ case Protocols.SHADOWSOCKS: return this.isSSMultiUser ? this.settings.shadowsockses : null;
+ default: return null;
+ }
+ }
+
get protocol() {
return this._protocol;
}
@@ -844,7 +854,7 @@ class Inbound extends XrayCommonClass {
this._protocol = protocol;
this.settings = Inbound.Settings.getSettings(protocol);
if (protocol === Protocols.TROJAN) {
- this.tls = true;
+ this.stream.isTls = true;
}
}
@@ -950,26 +960,8 @@ class Inbound extends XrayCommonClass {
}
isExpiry(index) {
- switch (this.protocol) {
- case Protocols.VMESS:
- if(this.settings.vmesses[index].expiryTime > 0)
- return this.settings.vmesses[index].expiryTime < new Date().getTime();
- return false
- case Protocols.VLESS:
- if(this.settings.vlesses[index].expiryTime > 0)
- return this.settings.vlesses[index].expiryTime < new Date().getTime();
- return false
- case Protocols.TROJAN:
- if(this.settings.trojans[index].expiryTime > 0)
- return this.settings.trojans[index].expiryTime < new Date().getTime();
- return false
- case Protocols.SHADOWSOCKS:
- if(this.settings.shadowsockses.length > 0 && this.settings.shadowsockses[index].expiryTime > 0)
- return this.settings.shadowsockses[index].expiryTime < new Date().getTime();
- return false
- default:
- return false;
- }
+ let exp = this.clients[index].expiryTime;
+ return exp > 0 ? exp < new Date().getTime() : false;
}
canEnableTls() {
@@ -1008,19 +1000,20 @@ class Inbound extends XrayCommonClass {
this.sniffing = new Sniffing();
}
- genVmessLink(address='', remark='', clientIndex=0) {
+ genVmessLink(address='', port=this.port, forceTls, remark='', clientId) {
if (this.protocol !== Protocols.VMESS) {
return '';
}
+ const security = forceTls == 'same' ? this.stream.security : forceTls;
let obj = {
v: '2',
ps: remark,
add: address,
- port: this.port,
- id: this.settings.vmesses[clientIndex].id,
+ port: port,
+ id: clientId,
net: this.stream.network,
type: 'none',
- tls: this.stream.security,
+ tls: security,
};
let network = this.stream.network;
if (network === 'tcp') {
@@ -1060,8 +1053,8 @@ class Inbound extends XrayCommonClass {
}
}
- if (this.stream.security === 'tls') {
- if (!ObjectUtil.isEmpty(this.stream.tls.server)) {
+ if (security === 'tls') {
+ if (address == this.listen && port == this.port && !ObjectUtil.isEmpty(this.stream.tls.server)) {
obj.add = this.stream.tls.server;
}
if (!ObjectUtil.isEmpty(this.stream.tls.settings.serverName)){
@@ -1081,11 +1074,10 @@ class Inbound extends XrayCommonClass {
return 'vmess://' + base64(JSON.stringify(obj, null, 2));
}
- genVLESSLink(address = '', remark='', clientIndex=0) {
- const settings = this.settings;
- const uuid = settings.vlesses[clientIndex].id;
- const port = this.port;
+ genVLESSLink(address = '', port=this.port, forceTls, remark='', clientId, flow) {
+ const uuid = clientId;
const type = this.stream.network;
+ const security = forceTls == 'same' ? this.stream.security : forceTls;
const params = new Map();
params.set("type", this.stream.network);
switch (type) {
@@ -1136,25 +1128,27 @@ class Inbound extends XrayCommonClass {
break;
}
- if (this.tls) {
+ if (security === 'tls') {
params.set("security", "tls");
- params.set("fp" , this.stream.tls.settings.fingerprint);
- params.set("alpn", this.stream.tls.alpn);
- if(this.stream.tls.settings.allowInsecure){
- params.set("allowInsecure", "1");
- }
- if (!ObjectUtil.isEmpty(this.stream.tls.server)) {
- address = this.stream.tls.server;
- }
- if (this.stream.tls.settings.serverName !== ''){
- params.set("sni", this.stream.tls.settings.serverName);
- }
- if (type === "tcp" && this.settings.vlesses[clientIndex].flow.length > 0) {
- params.set("flow", this.settings.vlesses[clientIndex].flow);
+ if (this.stream.isTls){
+ params.set("fp" , this.stream.tls.settings.fingerprint);
+ params.set("alpn", this.stream.tls.alpn);
+ if(this.stream.tls.settings.allowInsecure){
+ params.set("allowInsecure", "1");
+ }
+ if (!ObjectUtil.isEmpty(this.stream.tls.server)) {
+ address = this.stream.tls.server;
+ }
+ if (this.stream.tls.settings.serverName !== ''){
+ params.set("sni", this.stream.tls.settings.serverName);
+ }
+ if (type == "tcp" && !ObjectUtil.isEmpty(flow)) {
+ params.set("flow", flow);
+ }
}
}
- if (this.reality) {
+ if (security === 'reality') {
params.set("security", "reality");
params.set("pbk", this.stream.reality.settings.publicKey);
params.set("fp", this.stream.reality.settings.fingerprint);
@@ -1164,14 +1158,14 @@ class Inbound extends XrayCommonClass {
if (this.stream.reality.shortIds.length > 0) {
params.set("sid", this.stream.reality.shortIds.split(",")[0]);
}
- if (!ObjectUtil.isEmpty(this.stream.reality.settings.serverName)) {
+ if (address == this.listen && port == this.port && !ObjectUtil.isEmpty(this.stream.reality.settings.serverName)) {
address = this.stream.reality.settings.serverName;
}
if (!ObjectUtil.isEmpty(this.stream.reality.settings.spiderX)) {
params.set("spx", this.stream.reality.settings.spiderX);
}
- if (this.stream.network === 'tcp' && !ObjectUtil.isEmpty(this.settings.vlesses[clientIndex].flow)) {
- params.set("flow", this.settings.vlesses[clientIndex].flow);
+ if (type == 'tcp' && !ObjectUtil.isEmpty(flow)) {
+ params.set("flow", flow);
}
}
@@ -1184,9 +1178,8 @@ class Inbound extends XrayCommonClass {
return url.toString();
}
- genSSLink(address='', remark='', clientIndex = 0) {
+ genSSLink(address='', port=this.port, remark='', clientPassword) {
let settings = this.settings;
- const port = this.port;
const type = this.stream.network;
const params = new Map();
params.set("type", this.stream.network);
@@ -1240,9 +1233,9 @@ class Inbound extends XrayCommonClass {
let password = new Array();
if (this.isSS2022) password.push(settings.password);
- if (this.isSSMultiUser) password.push(settings.shadowsockses[clientIndex].password);
+ if (this.isSSMultiUser) password.push(clientPassword);
- let link = `ss://${safeBase64(settings.method + ':' + password.join(':'))}@${address}:${this.port}`;
+ let link = `ss://${safeBase64(settings.method + ':' + password.join(':'))}@${address}:${port}`;
const url = new URL(link);
for (const [key, value] of params) {
url.searchParams.set(key, value)
@@ -1251,9 +1244,8 @@ class Inbound extends XrayCommonClass {
return url.toString();
}
- genTrojanLink(address = '', remark = '', clientIndex = 0) {
- let settings = this.settings;
- const port = this.port;
+ genTrojanLink(address = '', port=this.port, forceTls, remark = '', clientPassword) {
+ const security = forceTls == 'same' ? this.stream.security : forceTls;
const type = this.stream.network;
const params = new Map();
params.set("type", this.stream.network);
@@ -1305,22 +1297,24 @@ class Inbound extends XrayCommonClass {
break;
}
- if (this.tls) {
+ if (security === 'tls') {
params.set("security", "tls");
- params.set("fp" , this.stream.tls.settings.fingerprint);
- params.set("alpn", this.stream.tls.alpn);
- if(this.stream.tls.settings.allowInsecure){
- params.set("allowInsecure", "1");
+ if (this.stream.isTls){
+ params.set("fp" , this.stream.tls.settings.fingerprint);
+ params.set("alpn", this.stream.tls.alpn);
+ if(this.stream.tls.settings.allowInsecure){
+ params.set("allowInsecure", "1");
+ }
+ if (address == this.listen && port == this.port && !ObjectUtil.isEmpty(this.stream.tls.server)) {
+ address = this.stream.tls.server;
+ }
+ if (this.stream.tls.settings.serverName !== ''){
+ params.set("sni", this.stream.tls.settings.serverName);
+ }
}
- if (!ObjectUtil.isEmpty(this.stream.tls.server)) {
- address = this.stream.tls.server;
- }
- if (this.stream.tls.settings.serverName !== ''){
- params.set("sni", this.stream.tls.settings.serverName);
- }
}
- if (this.reality) {
+ if (security === 'reality') {
params.set("security", "reality");
params.set("pbk", this.stream.reality.settings.publicKey);
params.set("fp", this.stream.reality.settings.fingerprint);
@@ -1330,7 +1324,7 @@ class Inbound extends XrayCommonClass {
if (this.stream.reality.shortIds.length > 0) {
params.set("sid", this.stream.reality.shortIds.split(",")[0]);
}
- if (!ObjectUtil.isEmpty(this.stream.reality.settings.serverName)) {
+ if (address == this.listen && port == this.port && !ObjectUtil.isEmpty(this.stream.reality.settings.serverName)) {
address = this.stream.reality.settings.serverName;
}
if (!ObjectUtil.isEmpty(this.stream.reality.settings.spiderX)) {
@@ -1338,7 +1332,7 @@ class Inbound extends XrayCommonClass {
}
}
- const link = `trojan://${settings.trojans[clientIndex].password}@${address}:${this.port}`;
+ const link = `trojan://${clientPassword}@${address}:${port}`;
const url = new URL(link);
for (const [key, value] of params) {
url.searchParams.set(key, value)
@@ -1347,38 +1341,62 @@ class Inbound extends XrayCommonClass {
return url.toString();
}
- genLink(address='', remark='', clientIndex=0) {
+ genLink(address='', port=this.port, forceTls='same', remark='', client) {
switch (this.protocol) {
case Protocols.VMESS:
- return this.genVmessLink(address, remark, clientIndex);
+ return this.genVmessLink(address, port, forceTls, remark, client.id);
case Protocols.VLESS:
- return this.genVLESSLink(address, remark, clientIndex);
+ return this.genVLESSLink(address, port, forceTls, remark, client.id, client.flow);
case Protocols.SHADOWSOCKS:
- return this.genSSLink(address, remark, clientIndex);
+ return this.genSSLink(address, port, remark, this.isSSMultiUser ? client.password : '');
case Protocols.TROJAN:
- return this.genTrojanLink(address, remark, clientIndex);
+ return this.genTrojanLink(address, port, forceTls, remark, client.password);
default: return '';
}
}
- genInboundLinks(address = '', remark = '') {
- let link = '';
- switch (this.protocol) {
- case Protocols.VMESS:
- case Protocols.VLESS:
- case Protocols.TROJAN:
- case Protocols.SHADOWSOCKS:
- JSON.parse(this.settings).clients.forEach((client,index) => {
- if(this.tls && !ObjectUtil.isArrEmpty(this.stream.tls.settings.domains)){
- this.stream.tls.settings.domains.forEach((domain) => {
- link += this.genLink(domain.domain, [remark, client.email, domain.remark].filter(x => x.length > 0).join('-'), index) + '\r\n';
- });
- } else {
- link += this.genLink(address, [remark, client.email].filter(x => x.length > 0).join('-'), index) + '\r\n';
- }
+ genAllLinks(remark='', client){
+ let result = [];
+ let email = client ? client.email : '';
+ let addr = this.listen;
+ let port = this.port
+ if(ObjectUtil.isArrEmpty(this.stream.externalProxy)){
+ let r = [remark, email].filter(x => x.length > 0).join('-');
+ result.push({
+ remark: r,
+ link: this.genLink(addr, port, 'same', r, client)
+ });
+ } else {
+ this.stream.externalProxy.forEach((ep) => {
+ let r = [remark, email, ep.remark].filter(x => x.length > 0).join('-')
+ let dest = ep.dest.split(":");
+ if(dest.length == 2) {
+ addr = dest[0];
+ port = dest[1];
+ } else {
+ addr = dest[0];
+ }
+ result.push({
+ remark: r,
+ link: this.genLink(addr, port, ep.forceTls, r, client)
});
- return link;
- default: return '';
+ });
+ }
+ return result;
+ }
+
+ genInboundLinks(remark = '') {
+ if(this.clients){
+ let links = [];
+ this.clients.forEach((client) => {
+ genAllLinks(remark,client).forEach(l => {
+ links.push(l.link);
+ })
+ });
+ return links.join('\r\n');
+ } else {
+ if(this.protocol == Protocols.SHADOWSOCKS && !this.isSSMultiUser) return this.genSSLink(this.listen, this.port, remark);
+ return '';
}
}
diff --git a/web/html/common/qrcode_modal.html b/web/html/common/qrcode_modal.html
index 8c0c13d7..75657301 100644
--- a/web/html/common/qrcode_modal.html
+++ b/web/html/common/qrcode_modal.html
@@ -19,39 +19,25 @@
const qrModal = {
title: '',
- clientIndex: 0,
- inbound: new Inbound(),
dbInbound: new DBInbound(),
client: null,
qrcodes: [],
clipboard: null,
visible: false,
subId: '',
- show: function (title = '', dbInbound = new DBInbound(), clientIndex = 0) {
+ show: function (title = '', dbInbound, client) {
this.title = title;
- this.clientIndex = clientIndex;
this.dbInbound = dbInbound;
this.inbound = dbInbound.toInbound();
- settings = JSON.parse(this.inbound.settings);
- this.client = settings.clients[clientIndex];
- remark = [this.dbInbound.remark, ( this.client ? this.client.email : '')].filter(Boolean).join('-');
- address = this.dbInbound.address;
+ this.client = client;
this.subId = '';
this.qrcodes = [];
- if (this.inbound.stream.isTls && !ObjectUtil.isArrEmpty(this.inbound.stream.tls.settings.domains)) {
- this.inbound.stream.tls.settings.domains.forEach((domain) => {
- remarkText = [remark, domain.remark].filter(Boolean).join('-');
- this.qrcodes.push({
- remark: remarkText,
- link: this.inbound.genLink(domain.domain, remarkText, clientIndex)
- });
- });
- } else {
+ this.inbound.genAllLinks(this.dbInbound.remark, client).forEach(l => {
this.qrcodes.push({
- remark: remark,
- link: this.inbound.genLink(address, remark, clientIndex)
+ remark: l.remark,
+ link: l.link
});
- }
+ });
this.visible = true;
},
close: function () {
diff --git a/web/html/xui/client_modal.html b/web/html/xui/client_modal.html
index 853b83a7..d85e6d4f 100644
--- a/web/html/xui/client_modal.html
+++ b/web/html/xui/client_modal.html
@@ -36,7 +36,7 @@
this.isEdit = isEdit;
this.dbInbound = new DBInbound(dbInbound);
this.inbound = dbInbound.toInbound();
- this.clients = this.getClients(this.inbound.protocol, this.inbound.settings);
+ this.clients = this.inbound.clients;
this.index = index === null ? this.clients.length : index;
this.delayedStart = false;
if (isEdit){
@@ -50,15 +50,6 @@
this.clientStats = this.dbInbound.clientStats.find(row => row.email === this.clients[this.index].email);
this.confirm = confirm;
},
- getClients(protocol, clientSettings) {
- switch(protocol){
- case Protocols.VMESS: return clientSettings.vmesses;
- case Protocols.VLESS: return clientSettings.vlesses;
- case Protocols.TROJAN: return clientSettings.trojans;
- case Protocols.SHADOWSOCKS: return clientSettings.shadowsockses;
- default: return null;
- }
- },
getClientId(protocol, client) {
switch(protocol){
case Protocols.TROJAN: return client.password;
diff --git a/web/html/xui/form/inbound.html b/web/html/xui/form/inbound.html
index 5707d153..e61b1259 100644
--- a/web/html/xui/form/inbound.html
+++ b/web/html/xui/form/inbound.html
@@ -126,6 +126,7 @@
{{template "form/streamSettings"}}
+ {{template "form/externalProxy" }}
diff --git a/web/html/xui/form/stream/external_proxy.html b/web/html/xui/form/stream/external_proxy.html
new file mode 100644
index 00000000..ef117464
--- /dev/null
+++ b/web/html/xui/form/stream/external_proxy.html
@@ -0,0 +1,29 @@
+{{define "form/externalProxy"}}
+
+
+
+
+ +
+
+
+
+ |
+
+
+
+
+ {{ i18n "pages.inbounds.same" }}
+ {{ i18n "none" }}
+ TLS
+
+
+
+
+
+ -
+
+ |
+
+
+
+{{end}}
\ No newline at end of file
diff --git a/web/html/xui/form/tls_settings.html b/web/html/xui/form/tls_settings.html
index 5754b650..3e4781fe 100644
--- a/web/html/xui/form/tls_settings.html
+++ b/web/html/xui/form/tls_settings.html
@@ -4,9 +4,8 @@
- | {{ i18n "security" }} |
-
-
+ |
+
{{ i18n "none" }}
TLS
@@ -64,26 +63,7 @@
|
|
-
- | Multi Domain |
-
-
- +
- |
-
-
- |
-
-
- [[ index+1 ]]
-
-
- -
-
-
- |
-
-
+
| {{ i18n "domainName" }} |
diff --git a/web/html/xui/inbound_info_modal.html b/web/html/xui/inbound_info_modal.html
index 27c90d37..16ced4e5 100644
--- a/web/html/xui/inbound_info_modal.html
+++ b/web/html/xui/inbound_info_modal.html
@@ -246,7 +246,6 @@
visible: false,
inbound: new Inbound(),
dbInbound: new DBInbound(),
- settings: null,
clientSettings: null,
clientStats: [],
upStats: 0,
@@ -261,27 +260,10 @@
this.index = index;
this.inbound = dbInbound.toInbound();
this.dbInbound = new DBInbound(dbInbound);
- this.settings = JSON.parse(this.inbound.settings);
- this.clientSettings = this.settings.clients ? Object.values(this.settings.clients)[index] : null;
- this.isExpired = this.inbound.isExpiry(index);
- this.clientStats = this.settings.clients ? this.dbInbound.clientStats.find(row => row.email === this.clientSettings.email) : [];
- remark = [this.dbInbound.remark, ( this.clientSettings ? this.clientSettings.email : '')].filter(Boolean).join('-');
- address = this.dbInbound.address;
- this.links = [];
- if (this.inbound.stream.isTls && !ObjectUtil.isArrEmpty(this.inbound.stream.tls.settings.domains)) {
- this.inbound.stream.tls.settings.domains.forEach((domain) => {
- remarkText = [remark, domain.remark].filter(Boolean).join('-');
- this.links.push({
- remark: remarkText,
- link: this.inbound.genLink(domain.domain, remarkText, index)
- });
- });
- } else {
- this.links.push({
- remark: remark,
- link: this.inbound.genLink(address, remark, index)
- });
- }
+ this.clientSettings = this.inbound.clients ? this.inbound.clients[index] : null;
+ this.isExpired = this.inbound.clients ? this.inbound.isExpiry(index): this.dbInbound.isExpiry;
+ this.clientStats = this.inbound.clients ? this.dbInbound.clientStats.find(row => row.email === this.clientSettings.email) : [];
+ this.links = this.inbound.genAllLinks(this.dbInbound.remark, this.clientSettings);
if (this.clientSettings) {
if (this.clientSettings.subId) {
this.subLink = this.genSubLink(this.clientSettings.subId);
diff --git a/web/html/xui/inbound_modal.html b/web/html/xui/inbound_modal.html
index dc39b8b8..ca9f4989 100644
--- a/web/html/xui/inbound_modal.html
+++ b/web/html/xui/inbound_modal.html
@@ -42,15 +42,6 @@
loading(loading) {
inModal.confirmLoading = loading;
},
- getClients(protocol, clientSettings) {
- switch(protocol){
- case Protocols.VMESS: return clientSettings.vmesses;
- case Protocols.VLESS: return clientSettings.vlesses;
- case Protocols.TROJAN: return clientSettings.trojans;
- case Protocols.SHADOWSOCKS: return clientSettings.shadowsockses;
- default: return null;
- }
- },
};
new Vue({
@@ -69,7 +60,7 @@
return inModal.isEdit;
},
get client() {
- return inModal.getClients(this.inbound.protocol, this.inbound.settings)[0];
+ return inModal.inbound.clients[0];
},
get delayedExpireDays() {
return this.client && this.client.expiryTime < 0 ? this.client.expiryTime / -86400000 : 0;
@@ -77,16 +68,18 @@
set delayedExpireDays(days){
this.client.expiryTime = -86400000 * days;
},
- get multiDomain() {
- return this.inbound.stream.tls.settings.domains.length > 0;
+ get externalProxy() {
+ return this.inbound.stream.externalProxy.length > 0;
},
- set multiDomain(value) {
+ set externalProxy(value) {
if (value) {
- inModal.inbound.stream.tls.server = "";
- inModal.inbound.stream.tls.settings.domains = [{ remark: "", domain: window.location.hostname }];
+ inModal.inbound.stream.externalProxy = [{
+ forceTls: "same",
+ dest: window.location.hostname + ":" + inModal.inbound.port,
+ remark: ""
+ }];
} else {
- inModal.inbound.stream.tls.server = "";
- inModal.inbound.stream.tls.settings.domains = [];
+ inModal.inbound.stream.externalProxy = [];
}
}
},
diff --git a/web/html/xui/inbounds.html b/web/html/xui/inbounds.html
index 7a700a34..86a4eee8 100644
--- a/web/html/xui/inbounds.html
+++ b/web/html/xui/inbounds.html
@@ -617,7 +617,7 @@
},
getClientCounts(dbInbound, inbound) {
let clientCount = 0, active = [], deactive = [], depleted = [], expiring = [], online = [];
- clients = this.getClients(dbInbound.protocol, inbound.settings);
+ clients = inbound.clients;
clientStats = dbInbound.clientStats
now = new Date().getTime()
if (clients) {
@@ -967,15 +967,6 @@
this.submit(`/xui/inbound/${dbInboundId}/delClient/${clientId}`);
}
},
- getClients(protocol, clientSettings) {
- switch (protocol) {
- case Protocols.VMESS: return clientSettings.vmesses;
- case Protocols.VLESS: return clientSettings.vlesses;
- case Protocols.TROJAN: return clientSettings.trojans;
- case Protocols.SHADOWSOCKS: return clientSettings.shadowsockses;
- default: return null;
- }
- },
getClientId(protocol, client) {
switch (protocol) {
case Protocols.TROJAN: return client.password;
@@ -995,7 +986,7 @@
newDbInbound.listen = rootInbound.listen;
newDbInbound.port = rootInbound.port;
newInbound = newDbInbound.toInbound();
- newInbound.stream.security = 'tls';
+ newInbound.stream.security = rootInbound.stream.security;
newInbound.stream.tls = rootInbound.stream.tls;
newDbInbound.streamSettings = newInbound.stream.toString();
}
@@ -1004,18 +995,15 @@
},
showQrcode(dbInboundId, client) {
dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
- inbound = dbInbound.toInbound();
- clients = this.getClients(dbInbound.protocol, inbound.settings);
- index = this.findIndexOfClient(dbInbound.protocol, clients, client);
newDbInbound = this.checkFallback(dbInbound);
- qrModal.show('{{ i18n "qrCode"}}', newDbInbound, index);
+ qrModal.show('{{ i18n "qrCode"}}', newDbInbound, client);
},
showInfo(dbInboundId, client) {
dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
index=0;
if (dbInbound.isMultiUser()){
inbound = dbInbound.toInbound();
- clients = this.getClients(dbInbound.protocol, inbound.settings);
+ clients = inbound.clients;
index = this.findIndexOfClient(dbInbound.protocol, clients, client);
}
newDbInbound = this.checkFallback(dbInbound);
@@ -1029,7 +1017,7 @@
this.loading()
dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
inbound = dbInbound.toInbound();
- clients = this.getClients(dbInbound.protocol, inbound.settings);
+ clients = inbound.clients;
index = this.findIndexOfClient(dbInbound.protocol, clients, client);
clients[index].enable = !clients[index].enable;
clientId = this.getClientId(dbInbound.protocol, clients[index]);
@@ -1043,15 +1031,7 @@
}
},
getInboundClients(dbInbound) {
- if (dbInbound.protocol == Protocols.VLESS) {
- return dbInbound.toInbound().settings.vlesses;
- } else if (dbInbound.protocol == Protocols.VMESS) {
- return dbInbound.toInbound().settings.vmesses;
- } else if (dbInbound.protocol == Protocols.TROJAN) {
- return dbInbound.toInbound().settings.trojans;
- } else if (dbInbound.protocol == Protocols.SHADOWSOCKS) {
- return dbInbound.toInbound().settings.shadowsockses;
- }
+ return dbInbound.toInbound().clients;
},
resetClientTraffic(client, dbInboundId, confirmation = true) {
if (confirmation){
@@ -1181,11 +1161,11 @@
txtModal.show('{{ i18n "pages.inbounds.export"}}', newDbInbound.genInboundLinks, newDbInbound.remark);
},
exportAllLinks() {
- let copyText = '';
+ let copyText = [];
for (const dbInbound of this.dbInbounds) {
- copyText += dbInbound.genInboundLinks;
+ copyText.push(dbInbound.genInboundLinks);
}
- txtModal.show('{{ i18n "pages.inbounds.export"}}', copyText, 'All-Inbounds');
+ txtModal.show('{{ i18n "pages.inbounds.export"}}', copyText.join('\r\n'), 'All-Inbounds');
},
async startDataRefreshLoop() {
while (this.isRefreshEnabled) {
diff --git a/web/service/xray.go b/web/service/xray.go
index ab434350..3827ba6d 100644
--- a/web/service/xray.go
+++ b/web/service/xray.go
@@ -133,19 +133,24 @@ func (s *XrayService) GetXrayConfig() (*xray.Config, error) {
inbound.Settings = string(modifiedSettings)
}
- // Unmarshal stream JSON
- var stream map[string]interface{}
- json.Unmarshal([]byte(inbound.StreamSettings), &stream)
+ if len(inbound.StreamSettings) > 0 {
+ // Unmarshal stream JSON
+ var stream map[string]interface{}
+ json.Unmarshal([]byte(inbound.StreamSettings), &stream)
- // Remove the "settings" field under "tlsSettings" and "realitySettings"
- tlsSettings, ok1 := stream["tlsSettings"].(map[string]interface{})
- realitySettings, ok2 := stream["realitySettings"].(map[string]interface{})
- if ok1 || ok2 {
- if ok1 {
- delete(tlsSettings, "settings")
- } else if ok2 {
- delete(realitySettings, "settings")
+ // Remove the "settings" field under "tlsSettings" and "realitySettings"
+ tlsSettings, ok1 := stream["tlsSettings"].(map[string]interface{})
+ realitySettings, ok2 := stream["realitySettings"].(map[string]interface{})
+ if ok1 || ok2 {
+ if ok1 {
+ delete(tlsSettings, "settings")
+ } else if ok2 {
+ delete(realitySettings, "settings")
+ }
}
+
+ delete(stream, "externalProxy")
+
newStream, err := json.MarshalIndent(stream, "", " ")
if err != nil {
return nil, err
diff --git a/web/translation/translate.en_US.toml b/web/translation/translate.en_US.toml
index f0e6619c..66b92219 100644
--- a/web/translation/translate.en_US.toml
+++ b/web/translation/translate.en_US.toml
@@ -169,6 +169,7 @@
"telegramDesc" = "Use Telegram ID without @ or chat IDs ( you can get it here @userinfobot or use '/id' command in bot )"
"subscriptionDesc" = "You can find your sub link on Details, also you can use the same name for several configurations"
"info" = "Info"
+"same" = "Same"
[pages.client]
"add" = "Add Client"
diff --git a/web/translation/translate.fa_IR.toml b/web/translation/translate.fa_IR.toml
index 38e13a5d..841c7475 100644
--- a/web/translation/translate.fa_IR.toml
+++ b/web/translation/translate.fa_IR.toml
@@ -168,6 +168,7 @@
"telegramDesc" = "از آیدی تلگرام بدون @ یا آیدی چت استفاده کنید (می توانید آن را از اینجا دریافت کنید @userinfobot یا در ربات دستور '/id' را وارد کنید)"
"subscriptionDesc" = "می توانید ساب لینک خود را در جزئیات پیدا کنید، همچنین می توانید از همین نام برای چندین کانفیگ استفاده کنید"
"info" = "اطلاعات"
+"same" = "همسان"
[pages.client]
"add" = "کاربر جدید"
diff --git a/web/translation/translate.ru_RU.toml b/web/translation/translate.ru_RU.toml
index 4dd1a292..dad8ea03 100644
--- a/web/translation/translate.ru_RU.toml
+++ b/web/translation/translate.ru_RU.toml
@@ -169,6 +169,7 @@
"telegramDesc" = "Используйте идентификатор Telegram без символа @ или идентификатора чата (можно получить его здесь @userinfobot или использовать команду '/id' в боте)"
"subscriptionDesc" = "вы можете найти свою ссылку подписки в разделе «Подробнее», также вы можете использовать одно и то же имя для нескольких конфигов"
"info" = "Информация"
+"same" = "Тот же"
[pages.client]
"add" = "Добавить клиента"
diff --git a/web/translation/translate.zh_Hans.toml b/web/translation/translate.zh_Hans.toml
index 9cae8bc0..b69a51ee 100644
--- a/web/translation/translate.zh_Hans.toml
+++ b/web/translation/translate.zh_Hans.toml
@@ -169,6 +169,7 @@
"telegramDesc" = "使用 Telegram ID,不包含 @ 符号或聊天 ID(可以在 @userinfobot 处获取,或在机器人中使用'/id'命令)"
"subscriptionDesc" = "您可以在详细信息上找到您的子链接,也可以对多个配置使用相同的名称"
"info" = "信息"
+"same" = "相同"
[pages.client]
"add" = "添加客户端"
|