Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/MHSanaei/3x-ui.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlireza Ahmadi <alireza7@gmail.com>2023-12-08 20:45:21 +0300
committerAlireza Ahmadi <alireza7@gmail.com>2023-12-08 20:45:21 +0300
commit5fbf8f0d535b131ad6de22a0d1dda0f2167d5ee0 (patch)
treec2da678a5d851fe5349644468427c5ba45e24d3d
parentbcc897640e68f7a731d39bee04c8930d7d7196c6 (diff)
Expand multiDomain to externalProxy #1300
-rw-r--r--sub/subService.go288
-rw-r--r--web/assets/js/model/xray.js255
-rw-r--r--web/html/common/qrcode_modal.html26
-rw-r--r--web/html/xui/client_modal.html13
-rw-r--r--web/html/xui/form/inbound.html1
-rw-r--r--web/html/xui/form/stream/external_proxy.html32
-rw-r--r--web/html/xui/form/tls_settings.html30
-rw-r--r--web/html/xui/inbound_info_modal.html25
-rw-r--r--web/html/xui/inbound_modal.html28
-rw-r--r--web/html/xui/inbounds.html46
-rw-r--r--web/service/inbound.go40
-rw-r--r--web/service/xray.go29
-rw-r--r--web/translation/translate.en_US.toml1
-rw-r--r--web/translation/translate.es_ES.toml1
-rw-r--r--web/translation/translate.fa_IR.toml1
-rw-r--r--web/translation/translate.ru_RU.toml1
-rw-r--r--web/translation/translate.vi_VN.toml1
-rw-r--r--web/translation/translate.zh_Hans.toml1
18 files changed, 453 insertions, 366 deletions
diff --git a/sub/subService.go b/sub/subService.go
index 23fad299..a1cbbb0f 100644
--- a/sub/subService.go
+++ b/sub/subService.go
@@ -53,6 +53,7 @@ func (s *SubService) GetSubs(subId string, host string, showInfo bool) ([]string
json.Unmarshal([]byte(fallbackMaster.StreamSettings), &masterStream)
stream["security"] = masterStream["security"]
stream["tlsSettings"] = masterStream["tlsSettings"]
+ stream["externalProxy"] = masterStream["externalProxy"]
modifiedStream, _ := json.MarshalIndent(stream, "", " ")
inbound.StreamSettings = string(modifiedStream)
}
@@ -96,7 +97,14 @@ func (s *SubService) GetSubs(subId string, host string, showInfo bool) ([]string
func (s *SubService) getInboundsBySubId(subId string) ([]*model.Inbound, error) {
db := database.GetDB()
var inbounds []*model.Inbound
- err := db.Model(model.Inbound{}).Preload("ClientStats").Where("settings like ? and enable = ?", fmt.Sprintf(`%%"subId": "%s"%%`, subId), true).Find(&inbounds).Error
+ err := db.Model(model.Inbound{}).Preload("ClientStats").Where(`id in (
+ SELECT DISTINCT inbounds.id
+ FROM inbounds,
+ JSON_EACH(JSON_EXTRACT(inbounds.settings, '$.clients')) AS client
+ WHERE
+ protocol in ('vmess','vless','trojan','shadowsocks')
+ AND JSON_EXTRACT(client.value, '$.subId') = ? AND enable = ?
+ )`, subId, true).Find(&inbounds).Error
if err != nil {
return nil, err
}
@@ -196,7 +204,6 @@ func (s *SubService) genVmessLink(inbound *model.Inbound, email string) string {
}
security, _ := stream["security"].(string)
- var domains []interface{}
obj["tls"] = security
if security == "tls" {
tlsSetting, _ := stream["tlsSettings"].(map[string]interface{})
@@ -208,24 +215,18 @@ func (s *SubService) genVmessLink(inbound *model.Inbound, email string) string {
}
obj["alpn"] = strings.Join(alpn, ",")
}
+ if sniValue, ok := searchKey(tlsSetting, "serverName"); ok {
+ obj["sni"], _ = sniValue.(string)
+ }
+
tlsSettings, _ := searchKey(tlsSetting, "settings")
if tlsSetting != nil {
- if sniValue, ok := searchKey(tlsSettings, "serverName"); ok {
- obj["sni"], _ = sniValue.(string)
- }
if fpValue, ok := searchKey(tlsSettings, "fingerprint"); ok {
obj["fp"], _ = fpValue.(string)
}
if insecure, ok := searchKey(tlsSettings, "allowInsecure"); ok {
obj["allowInsecure"], _ = insecure.(bool)
}
- if domainSettings, ok := searchKey(tlsSettings, "domains"); ok {
- domains, _ = domainSettings.([]interface{})
- }
- }
- serverName, _ := tlsSetting["serverName"].(string)
- if serverName != "" {
- obj["add"] = serverName
}
}
@@ -239,16 +240,30 @@ func (s *SubService) genVmessLink(inbound *model.Inbound, email string) string {
}
obj["id"] = clients[clientIndex].ID
- if len(domains) > 0 {
+ externalProxies, _ := stream["externalProxy"].([]interface{})
+
+ if len(externalProxies) > 0 {
links := ""
- for index, d := range domains {
- domain := d.(map[string]interface{})
- obj["ps"] = s.genRemark(inbound, email, domain["remark"].(string))
- obj["add"] = domain["domain"].(string)
+ for index, externalProxy := range externalProxies {
+ ep, _ := externalProxy.(map[string]interface{})
+ newSecurity, _ := ep["forceTls"].(string)
+ newObj := map[string]interface{}{}
+ for key, value := range obj {
+ if !(newSecurity == "none" && (key == "alpn" || key == "sni" || key == "fp" || key == "allowInsecure")) {
+ newObj[key] = value
+ }
+ }
+ newObj["ps"] = s.genRemark(inbound, email, ep["remark"].(string))
+ newObj["add"] = ep["dest"].(string)
+ newObj["port"] = int(ep["port"].(float64))
+
+ if newSecurity != "same" {
+ newObj["tls"] = newSecurity
+ }
if index > 0 {
links += "\n"
}
- jsonStr, _ := json.MarshalIndent(obj, "", " ")
+ jsonStr, _ := json.MarshalIndent(newObj, "", " ")
links += "vmess://" + base64.StdEncoding.EncodeToString(jsonStr)
}
return links
@@ -323,7 +338,6 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string {
}
security, _ := stream["security"].(string)
- var domains []interface{}
if security == "tls" {
params["security"] = "tls"
tlsSetting, _ := stream["tlsSettings"].(map[string]interface{})
@@ -335,11 +349,12 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string {
if len(alpn) > 0 {
params["alpn"] = strings.Join(alpn, ",")
}
+ if sniValue, ok := searchKey(tlsSetting, "serverName"); ok {
+ params["sni"], _ = sniValue.(string)
+ }
+
tlsSettings, _ := searchKey(tlsSetting, "settings")
if tlsSetting != nil {
- if sniValue, ok := searchKey(tlsSettings, "serverName"); ok {
- params["sni"], _ = sniValue.(string)
- }
if fpValue, ok := searchKey(tlsSettings, "fingerprint"); ok {
params["fp"], _ = fpValue.(string)
}
@@ -348,19 +363,11 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string {
params["allowInsecure"] = "1"
}
}
- if domainSettings, ok := searchKey(tlsSettings, "domains"); ok {
- domains, _ = domainSettings.([]interface{})
- }
}
if streamNetwork == "tcp" && len(clients[clientIndex].Flow) > 0 {
params["flow"] = clients[clientIndex].Flow
}
-
- serverName, _ := tlsSetting["serverName"].(string)
- if serverName != "" {
- address = serverName
- }
}
if security == "reality" {
@@ -389,11 +396,6 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string {
params["spx"] = spx
}
}
- if serverName, ok := searchKey(realitySettings, "serverName"); ok {
- if sname, ok := serverName.(string); ok && len(sname) > 0 {
- address = sname
- }
- }
}
if streamNetwork == "tcp" && len(clients[clientIndex].Flow) > 0 {
@@ -412,7 +414,9 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string {
if len(alpn) > 0 {
params["alpn"] = strings.Join(alpn, ",")
}
-
+ if sniValue, ok := searchKey(xtlsSetting, "serverName"); ok {
+ params["sni"], _ = sniValue.(string)
+ }
xtlsSettings, _ := searchKey(xtlsSetting, "settings")
if xtlsSetting != nil {
if fpValue, ok := searchKey(xtlsSettings, "fingerprint"); ok {
@@ -423,42 +427,47 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string {
params["allowInsecure"] = "1"
}
}
- if sniValue, ok := searchKey(xtlsSettings, "serverName"); ok {
- params["sni"], _ = sniValue.(string)
- }
}
if streamNetwork == "tcp" && len(clients[clientIndex].Flow) > 0 {
params["flow"] = clients[clientIndex].Flow
}
-
- serverName, _ := xtlsSetting["serverName"].(string)
- if serverName != "" {
- address = serverName
- }
}
if security != "tls" && security != "reality" && security != "xtls" {
params["security"] = "none"
}
- link := fmt.Sprintf("vless://%s@%s:%d", uuid, address, port)
- url, _ := url.Parse(link)
- q := url.Query()
+ externalProxies, _ := stream["externalProxy"].([]interface{})
- for k, v := range params {
- q.Add(k, v)
- }
+ if len(externalProxies) > 0 {
+ links := ""
+ for index, externalProxy := range externalProxies {
+ ep, _ := externalProxy.(map[string]interface{})
+ newSecurity, _ := ep["forceTls"].(string)
+ dest, _ := ep["dest"].(string)
+ port := int(ep["port"].(float64))
+ link := fmt.Sprintf("vless://%s@%s:%d", uuid, dest, port)
+
+ if newSecurity != "same" {
+ params["security"] = newSecurity
+ } else {
+ params["security"] = security
+ }
+ url, _ := url.Parse(link)
+ q := url.Query()
- // Set the new query values on the URL
- url.RawQuery = q.Encode()
+ for k, v := range params {
+ if !(newSecurity == "none" && (k == "alpn" || k == "sni" || k == "fp" || k == "allowInsecure")) {
+ q.Add(k, v)
+ }
+ }
+
+ // Set the new query values on the URL
+ url.RawQuery = q.Encode()
+
+ url.Fragment = s.genRemark(inbound, email, ep["remark"].(string))
- if len(domains) > 0 {
- links := ""
- for index, d := range domains {
- domain := d.(map[string]interface{})
- url.Fragment = s.genRemark(inbound, email, domain["remark"].(string))
- url.Host = fmt.Sprintf("%s:%d", domain["domain"].(string), port)
if index > 0 {
links += "\n"
}
@@ -467,6 +476,17 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string {
return links
}
+ link := fmt.Sprintf("vless://%s@%s:%d", uuid, address, port)
+ url, _ := url.Parse(link)
+ q := url.Query()
+
+ for k, v := range params {
+ q.Add(k, v)
+ }
+
+ // Set the new query values on the URL
+ url.RawQuery = q.Encode()
+
url.Fragment = s.genRemark(inbound, email, "")
return url.String()
}
@@ -534,7 +554,6 @@ func (s *SubService) genTrojanLink(inbound *model.Inbound, email string) string
}
security, _ := stream["security"].(string)
- var domains []interface{}
if security == "tls" {
params["security"] = "tls"
tlsSetting, _ := stream["tlsSettings"].(map[string]interface{})
@@ -546,11 +565,11 @@ func (s *SubService) genTrojanLink(inbound *model.Inbound, email string) string
if len(alpn) > 0 {
params["alpn"] = strings.Join(alpn, ",")
}
+ if sniValue, ok := searchKey(tlsSetting, "serverName"); ok {
+ params["sni"], _ = sniValue.(string)
+ }
tlsSettings, _ := searchKey(tlsSetting, "settings")
if tlsSetting != nil {
- if sniValue, ok := searchKey(tlsSettings, "serverName"); ok {
- params["sni"], _ = sniValue.(string)
- }
if fpValue, ok := searchKey(tlsSettings, "fingerprint"); ok {
params["fp"], _ = fpValue.(string)
}
@@ -559,14 +578,6 @@ func (s *SubService) genTrojanLink(inbound *model.Inbound, email string) string
params["allowInsecure"] = "1"
}
}
- if domainSettings, ok := searchKey(tlsSettings, "domains"); ok {
- domains, _ = domainSettings.([]interface{})
- }
- }
-
- serverName, _ := tlsSetting["serverName"].(string)
- if serverName != "" {
- address = serverName
}
}
@@ -596,11 +607,6 @@ func (s *SubService) genTrojanLink(inbound *model.Inbound, email string) string
params["spx"] = spx
}
}
- if serverName, ok := searchKey(realitySettings, "serverName"); ok {
- if sname, ok := serverName.(string); ok && len(sname) > 0 {
- address = sname
- }
- }
}
if streamNetwork == "tcp" && len(clients[clientIndex].Flow) > 0 {
@@ -619,6 +625,9 @@ func (s *SubService) genTrojanLink(inbound *model.Inbound, email string) string
if len(alpn) > 0 {
params["alpn"] = strings.Join(alpn, ",")
}
+ if sniValue, ok := searchKey(xtlsSetting, "serverName"); ok {
+ params["sni"], _ = sniValue.(string)
+ }
xtlsSettings, _ := searchKey(xtlsSetting, "settings")
if xtlsSetting != nil {
@@ -630,43 +639,47 @@ func (s *SubService) genTrojanLink(inbound *model.Inbound, email string) string
params["allowInsecure"] = "1"
}
}
- if sniValue, ok := searchKey(xtlsSettings, "serverName"); ok {
- params["sni"], _ = sniValue.(string)
- }
}
if streamNetwork == "tcp" && len(clients[clientIndex].Flow) > 0 {
params["flow"] = clients[clientIndex].Flow
}
-
- serverName, _ := xtlsSetting["serverName"].(string)
- if serverName != "" {
- address = serverName
- }
}
if security != "tls" && security != "reality" && security != "xtls" {
params["security"] = "none"
}
- link := fmt.Sprintf("trojan://%s@%s:%d", password, address, port)
+ externalProxies, _ := stream["externalProxy"].([]interface{})
- url, _ := url.Parse(link)
- q := url.Query()
+ if len(externalProxies) > 0 {
+ links := ""
+ for index, externalProxy := range externalProxies {
+ ep, _ := externalProxy.(map[string]interface{})
+ newSecurity, _ := ep["forceTls"].(string)
+ dest, _ := ep["dest"].(string)
+ port := int(ep["port"].(float64))
+ link := fmt.Sprintf("trojan://%s@%s:%d", password, dest, port)
+
+ if newSecurity != "same" {
+ params["security"] = newSecurity
+ } else {
+ params["security"] = security
+ }
+ url, _ := url.Parse(link)
+ q := url.Query()
- for k, v := range params {
- q.Add(k, v)
- }
+ for k, v := range params {
+ if !(newSecurity == "none" && (k == "alpn" || k == "sni" || k == "fp" || k == "allowInsecure")) {
+ q.Add(k, v)
+ }
+ }
- // Set the new query values on the URL
- url.RawQuery = q.Encode()
+ // Set the new query values on the URL
+ url.RawQuery = q.Encode()
+
+ url.Fragment = s.genRemark(inbound, email, ep["remark"].(string))
- if len(domains) > 0 {
- links := ""
- for index, d := range domains {
- domain := d.(map[string]interface{})
- url.Fragment = s.genRemark(inbound, email, domain["remark"].(string))
- url.Host = fmt.Sprintf("%s:%d", domain["domain"].(string), port)
if index > 0 {
links += "\n"
}
@@ -675,6 +688,18 @@ func (s *SubService) genTrojanLink(inbound *model.Inbound, email string) string
return links
}
+ link := fmt.Sprintf("trojan://%s@%s:%d", password, address, port)
+
+ url, _ := url.Parse(link)
+ q := url.Query()
+
+ for k, v := range params {
+ q.Add(k, v)
+ }
+
+ // Set the new query values on the URL
+ url.RawQuery = q.Encode()
+
url.Fragment = s.genRemark(inbound, email, "")
return url.String()
}
@@ -744,10 +769,78 @@ func (s *SubService) genShadowsocksLink(inbound *model.Inbound, email string) st
}
}
+ security, _ := stream["security"].(string)
+ if security == "tls" {
+ params["security"] = "tls"
+ tlsSetting, _ := stream["tlsSettings"].(map[string]interface{})
+ alpns, _ := tlsSetting["alpn"].([]interface{})
+ var alpn []string
+ for _, a := range alpns {
+ alpn = append(alpn, a.(string))
+ }
+ if len(alpn) > 0 {
+ params["alpn"] = strings.Join(alpn, ",")
+ }
+ if sniValue, ok := searchKey(tlsSetting, "serverName"); ok {
+ params["sni"], _ = sniValue.(string)
+ }
+
+ tlsSettings, _ := searchKey(tlsSetting, "settings")
+ if tlsSetting != nil {
+ if fpValue, ok := searchKey(tlsSettings, "fingerprint"); ok {
+ params["fp"], _ = fpValue.(string)
+ }
+ if insecure, ok := searchKey(tlsSettings, "allowInsecure"); ok {
+ if insecure.(bool) {
+ params["allowInsecure"] = "1"
+ }
+ }
+ }
+ }
+
encPart := fmt.Sprintf("%s:%s", method, clients[clientIndex].Password)
if method[0] == '2' {
encPart = fmt.Sprintf("%s:%s:%s", method, inboundPassword, clients[clientIndex].Password)
}
+
+ externalProxies, _ := stream["externalProxy"].([]interface{})
+
+ if len(externalProxies) > 0 {
+ links := ""
+ for index, externalProxy := range externalProxies {
+ ep, _ := externalProxy.(map[string]interface{})
+ newSecurity, _ := ep["forceTls"].(string)
+ dest, _ := ep["dest"].(string)
+ port := int(ep["port"].(float64))
+ link := fmt.Sprintf("ss://%s@%s:%d", base64.StdEncoding.EncodeToString([]byte(encPart)), dest, port)
+
+ if newSecurity != "same" {
+ params["security"] = newSecurity
+ } else {
+ params["security"] = security
+ }
+ url, _ := url.Parse(link)
+ q := url.Query()
+
+ for k, v := range params {
+ if !(newSecurity == "none" && (k == "alpn" || k == "sni" || k == "fp" || k == "allowInsecure")) {
+ q.Add(k, v)
+ }
+ }
+
+ // Set the new query values on the URL
+ url.RawQuery = q.Encode()
+
+ url.Fragment = s.genRemark(inbound, email, ep["remark"].(string))
+
+ if index > 0 {
+ links += "\n"
+ }
+ links += url.String()
+ }
+ return links
+ }
+
link := fmt.Sprintf("ss://%s@%s:%d", base64.StdEncoding.EncodeToString([]byte(encPart)), address, inbound.Port)
url, _ := url.Parse(link)
q := url.Query()
@@ -758,6 +851,7 @@ func (s *SubService) genShadowsocksLink(inbound *model.Inbound, email string) st
// Set the new query values on the URL
url.RawQuery = q.Encode()
+
url.Fragment = s.genRemark(inbound, email, "")
return url.String()
}
diff --git a/web/assets/js/model/xray.js b/web/assets/js/model/xray.js
index 0418540a..97110ae9 100644
--- a/web/assets/js/model/xray.js
+++ b/web/assets/js/model/xray.js
@@ -578,27 +578,21 @@ TlsStreamSettings.Cert = class extends XrayCommonClass {
};
TlsStreamSettings.Settings = class extends XrayCommonClass {
- constructor(allowInsecure = false, fingerprint = '', serverName = '', domains = []) {
+ constructor(allowInsecure = false, fingerprint = '') {
super();
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() {
return {
allowInsecure: this.allowInsecure,
fingerprint: this.fingerprint,
- serverName: this.serverName,
- domains: this.domains,
};
}
};
@@ -692,21 +686,18 @@ XtlsStreamSettings.Cert = class extends XrayCommonClass {
};
XtlsStreamSettings.Settings = class extends XrayCommonClass {
- constructor(allowInsecure = false, serverName = '') {
+ constructor(allowInsecure = false) {
super();
this.allowInsecure = allowInsecure;
- this.serverName = serverName;
}
static fromJson(json = {}) {
return new XtlsStreamSettings.Settings(
json.allowInsecure,
- json.servername,
);
}
toJson() {
return {
allowInsecure: this.allowInsecure,
- serverName: this.serverName,
};
}
};
@@ -773,18 +764,16 @@ class RealityStreamSettings extends XrayCommonClass {
}
RealityStreamSettings.Settings = class extends XrayCommonClass {
- constructor(publicKey = '', fingerprint = UTLS_FINGERPRINT.UTLS_FIREFOX, serverName = '', spiderX= '/') {
+ constructor(publicKey = '', fingerprint = UTLS_FINGERPRINT.UTLS_FIREFOX, spiderX= '/') {
super();
this.publicKey = publicKey;
this.fingerprint = fingerprint;
- this.serverName = serverName;
this.spiderX = spiderX;
}
static fromJson(json = {}) {
return new RealityStreamSettings.Settings(
json.publicKey,
json.fingerprint,
- json.serverName,
json.spiderX,
);
}
@@ -792,7 +781,6 @@ RealityStreamSettings.Settings = class extends XrayCommonClass {
return {
publicKey: this.publicKey,
fingerprint: this.fingerprint,
- serverName: this.serverName,
spiderX: this.spiderX,
};
}
@@ -829,6 +817,7 @@ class SockoptStreamSettings extends XrayCommonClass {
class StreamSettings extends XrayCommonClass {
constructor(network='tcp',
security='none',
+ externalProxy = [],
tlsSettings=new TlsStreamSettings(),
xtlsSettings=new XtlsStreamSettings(),
realitySettings = new RealityStreamSettings(),
@@ -843,6 +832,7 @@ class StreamSettings extends XrayCommonClass {
super();
this.network = network;
this.security = security;
+ this.externalProxy = externalProxy;
this.tls = tlsSettings;
this.xtls = xtlsSettings;
this.reality = realitySettings;
@@ -901,10 +891,10 @@ class StreamSettings extends XrayCommonClass {
}
static fromJson(json={}) {
-
return new StreamSettings(
json.network,
json.security,
+ json.externalProxy,
TlsStreamSettings.fromJson(json.tlsSettings),
XtlsStreamSettings.fromJson(json.xtlsSettings),
RealityStreamSettings.fromJson(json.realitySettings),
@@ -923,6 +913,7 @@ class StreamSettings extends XrayCommonClass {
return {
network: network,
security: this.security,
+ externalProxy: this.externalProxy,
tlsSettings: this.isTls ? this.tls.toJson() : undefined,
xtlsSettings: this.isXtls ? this.xtls.toJson() : undefined,
realitySettings: this.isReality ? this.reality.toJson() : undefined,
@@ -982,6 +973,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;
}
@@ -1132,26 +1133,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() {
@@ -1195,19 +1178,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') {
@@ -1247,12 +1231,9 @@ class Inbound extends XrayCommonClass {
}
}
- if (this.stream.security === 'tls') {
- if (!ObjectUtil.isEmpty(this.stream.tls.server)) {
- obj.add = this.stream.tls.server;
- }
- if (!ObjectUtil.isEmpty(this.stream.tls.settings.serverName)){
- obj.sni = this.stream.tls.settings.serverName;
+ if (security === 'tls') {
+ if (!ObjectUtil.isEmpty(this.stream.tls.sni)){
+ obj.sni = this.stream.tls.server;
}
if (!ObjectUtil.isEmpty(this.stream.tls.settings.fingerprint)){
obj.fp = this.stream.tls.settings.fingerprint;
@@ -1268,11 +1249,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) {
@@ -1323,58 +1303,51 @@ 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)){
+ params.set("sni", this.stream.tls.server);
+ }
+ if (type == "tcp" && !ObjectUtil.isEmpty(flow)) {
+ params.set("flow", flow);
+ }
}
}
- else if (this.xtls) {
+ else if (security === 'xtls') {
params.set("security", "xtls");
params.set("alpn", this.stream.xtls.alpn);
if(this.stream.xtls.settings.allowInsecure){
params.set("allowInsecure", "1");
}
- if (!ObjectUtil.isEmpty(this.stream.xtls.server)) {
- address = this.stream.xtls.server;
- }
- if (this.stream.xtls.settings.serverName !== ''){
- params.set("sni", this.stream.xtls.settings.serverName);
+ if (!ObjectUtil.isEmpty(this.stream.xtls.server)){
+ params.set("sni", this.stream.xtls.server);
}
params.set("flow", this.settings.vlesses[clientIndex].flow);
}
- else if (this.reality) {
+ else if (security === 'reality') {
params.set("security", "reality");
- params.set("fp", this.stream.reality.settings.fingerprint);
params.set("pbk", this.stream.reality.settings.publicKey);
+ params.set("fp", this.stream.reality.settings.fingerprint);
if (!ObjectUtil.isArrEmpty(this.stream.reality.serverNames)) {
params.set("sni", this.stream.reality.serverNames.split(",")[0]);
}
- if (this.stream.network === 'tcp' && !ObjectUtil.isEmpty(this.settings.vlesses[clientIndex].flow)) {
- params.set("flow", this.settings.vlesses[clientIndex].flow);
- }
if (this.stream.reality.shortIds.length > 0) {
params.set("sid", this.stream.reality.shortIds.split(",")[0]);
}
- if (!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 (type == 'tcp' && !ObjectUtil.isEmpty(flow)) {
+ params.set("flow", flow);
+ }
}
else {
@@ -1390,10 +1363,10 @@ class Inbound extends XrayCommonClass {
return url.toString();
}
- genSSLink(address='', remark='', clientIndex = 0) {
+ genSSLink(address='', port=this.port, forceTls, remark='', clientPassword) {
let settings = this.settings;
- const port = this.port;
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) {
@@ -1444,11 +1417,26 @@ class Inbound extends XrayCommonClass {
break;
}
+ if (security === 'tls') {
+ params.set("security", "tls");
+ 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)){
+ params.set("sni", this.stream.tls.server);
+ }
+ }
+ }
+
+
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)
@@ -1457,9 +1445,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);
@@ -1511,48 +1498,41 @@ 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.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)){
+ params.set("sni", this.stream.tls.server);
+ }
}
- if (this.stream.tls.settings.serverName !== ''){
- params.set("sni", this.stream.tls.settings.serverName);
- }
}
- else if (this.reality) {
+ else if (security === 'reality') {
params.set("security", "reality");