mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-08-30 14:56:17 +00:00
Merge branch 'MHSanaei:main' into main
This commit is contained in:
commit
b1cd912ddf
13 changed files with 70 additions and 86 deletions
4
go.mod
4
go.mod
|
@ -18,8 +18,8 @@ require (
|
||||||
go.uber.org/atomic v1.11.0
|
go.uber.org/atomic v1.11.0
|
||||||
golang.org/x/text v0.9.0
|
golang.org/x/text v0.9.0
|
||||||
google.golang.org/grpc v1.55.0
|
google.golang.org/grpc v1.55.0
|
||||||
gorm.io/driver/sqlite v1.5.1
|
gorm.io/driver/sqlite v1.5.2
|
||||||
gorm.io/gorm v1.25.1
|
gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|
8
go.sum
8
go.sum
|
@ -272,10 +272,10 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gorm.io/driver/sqlite v1.5.1 h1:hYyrLkAWE71bcarJDPdZNTLWtr8XrSjOWyjUYI6xdL4=
|
gorm.io/driver/sqlite v1.5.2 h1:TpQ+/dqCY4uCigCFyrfnrJnrW9zjpelWVoEVNy5qJkc=
|
||||||
gorm.io/driver/sqlite v1.5.1/go.mod h1:7MZZ2Z8bqyfSQA1gYEV6MagQWj3cpUkJj9Z+d1HEMEQ=
|
gorm.io/driver/sqlite v1.5.2/go.mod h1:qxAuCol+2r6PannQDpOP1FP6ag3mKi4esLnB/jHed+4=
|
||||||
gorm.io/gorm v1.25.1 h1:nsSALe5Pr+cM3V1qwwQ7rOkw+6UeLrX5O4v3llhHa64=
|
gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55 h1:sC1Xj4TYrLqg1n3AN10w871An7wJM0gzgcm8jkIkECQ=
|
||||||
gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||||
gvisor.dev/gvisor v0.0.0-20220901235040-6ca97ef2ce1c h1:m5lcgWnL3OElQNVyp3qcncItJ2c0sQlSGjYK2+nJTA4=
|
gvisor.dev/gvisor v0.0.0-20220901235040-6ca97ef2ce1c h1:m5lcgWnL3OElQNVyp3qcncItJ2c0sQlSGjYK2+nJTA4=
|
||||||
lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0=
|
lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0=
|
||||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||||
|
|
|
@ -4,7 +4,6 @@ const Protocols = {
|
||||||
TROJAN: 'trojan',
|
TROJAN: 'trojan',
|
||||||
SHADOWSOCKS: 'shadowsocks',
|
SHADOWSOCKS: 'shadowsocks',
|
||||||
DOKODEMO: 'dokodemo-door',
|
DOKODEMO: 'dokodemo-door',
|
||||||
MTPROTO: 'mtproto',
|
|
||||||
SOCKS: 'socks',
|
SOCKS: 'socks',
|
||||||
HTTP: 'http',
|
HTTP: 'http',
|
||||||
};
|
};
|
||||||
|
@ -379,10 +378,15 @@ class WsStreamSettings extends XrayCommonClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
class HttpStreamSettings extends XrayCommonClass {
|
class HttpStreamSettings extends XrayCommonClass {
|
||||||
constructor(path='/', host=['']) {
|
constructor(
|
||||||
|
path='/',
|
||||||
|
host=[''],
|
||||||
|
sockopt={acceptProxyProtocol: false}
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
this.path = path;
|
this.path = path;
|
||||||
this.host = host.length === 0 ? [''] : host;
|
this.host = host.length === 0 ? [''] : host;
|
||||||
|
this.sockopt = sockopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
addHost(host) {
|
addHost(host) {
|
||||||
|
@ -394,7 +398,7 @@ class HttpStreamSettings extends XrayCommonClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromJson(json={}) {
|
static fromJson(json={}) {
|
||||||
return new HttpStreamSettings(json.path, json.host);
|
return new HttpStreamSettings(json.path, json.host, json.sockopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
toJson() {
|
toJson() {
|
||||||
|
@ -407,10 +411,12 @@ class HttpStreamSettings extends XrayCommonClass {
|
||||||
return {
|
return {
|
||||||
path: this.path,
|
path: this.path,
|
||||||
host: host,
|
host: host,
|
||||||
|
sockopt: this.sockopt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class QuicStreamSettings extends XrayCommonClass {
|
class QuicStreamSettings extends XrayCommonClass {
|
||||||
constructor(security=VmessMethods.NONE,
|
constructor(security=VmessMethods.NONE,
|
||||||
key='', type='none') {
|
key='', type='none') {
|
||||||
|
@ -442,33 +448,39 @@ class QuicStreamSettings extends XrayCommonClass {
|
||||||
class GrpcStreamSettings extends XrayCommonClass {
|
class GrpcStreamSettings extends XrayCommonClass {
|
||||||
constructor(
|
constructor(
|
||||||
serviceName="",
|
serviceName="",
|
||||||
multiMode=false
|
multiMode=false,
|
||||||
|
sockopt={acceptProxyProtocol: false}
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this.serviceName = serviceName;
|
this.serviceName = serviceName;
|
||||||
this.multiMode = multiMode;
|
this.multiMode = multiMode;
|
||||||
|
this.sockopt = sockopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromJson(json={}) {
|
static fromJson(json={}) {
|
||||||
return new GrpcStreamSettings(
|
return new GrpcStreamSettings(
|
||||||
json.serviceName,
|
json.serviceName,
|
||||||
json.multiMode
|
json.multiMode,
|
||||||
|
json.sockopt
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
toJson() {
|
toJson() {
|
||||||
return {
|
return {
|
||||||
serviceName: this.serviceName,
|
serviceName: this.serviceName,
|
||||||
multiMode: this.multiMode
|
multiMode: this.multiMode,
|
||||||
|
sockopt: this.sockopt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class TlsStreamSettings extends XrayCommonClass {
|
class TlsStreamSettings extends XrayCommonClass {
|
||||||
constructor(serverName='',
|
constructor(serverName='',
|
||||||
minVersion = TLS_VERSION_OPTION.TLS12,
|
minVersion = TLS_VERSION_OPTION.TLS12,
|
||||||
maxVersion = TLS_VERSION_OPTION.TLS13,
|
maxVersion = TLS_VERSION_OPTION.TLS13,
|
||||||
cipherSuites = '',
|
cipherSuites = '',
|
||||||
|
rejectUnknownSni = false,
|
||||||
certificates=[new TlsStreamSettings.Cert()],
|
certificates=[new TlsStreamSettings.Cert()],
|
||||||
alpn=[ALPN_OPTION.H2,ALPN_OPTION.HTTP1],
|
alpn=[ALPN_OPTION.H2,ALPN_OPTION.HTTP1],
|
||||||
settings=new TlsStreamSettings.Settings()) {
|
settings=new TlsStreamSettings.Settings()) {
|
||||||
|
@ -477,6 +489,7 @@ class TlsStreamSettings extends XrayCommonClass {
|
||||||
this.minVersion = minVersion;
|
this.minVersion = minVersion;
|
||||||
this.maxVersion = maxVersion;
|
this.maxVersion = maxVersion;
|
||||||
this.cipherSuites = cipherSuites;
|
this.cipherSuites = cipherSuites;
|
||||||
|
this.rejectUnknownSni = rejectUnknownSni;
|
||||||
this.certs = certificates;
|
this.certs = certificates;
|
||||||
this.alpn = alpn;
|
this.alpn = alpn;
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
|
@ -504,6 +517,7 @@ class TlsStreamSettings extends XrayCommonClass {
|
||||||
json.minVersion,
|
json.minVersion,
|
||||||
json.maxVersion,
|
json.maxVersion,
|
||||||
json.cipherSuites,
|
json.cipherSuites,
|
||||||
|
json.rejectUnknownSni,
|
||||||
certs,
|
certs,
|
||||||
json.alpn,
|
json.alpn,
|
||||||
settings,
|
settings,
|
||||||
|
@ -516,6 +530,7 @@ class TlsStreamSettings extends XrayCommonClass {
|
||||||
minVersion: this.minVersion,
|
minVersion: this.minVersion,
|
||||||
maxVersion: this.maxVersion,
|
maxVersion: this.maxVersion,
|
||||||
cipherSuites: this.cipherSuites,
|
cipherSuites: this.cipherSuites,
|
||||||
|
rejectUnknownSni: this.rejectUnknownSni,
|
||||||
certificates: TlsStreamSettings.toJsonArray(this.certs),
|
certificates: TlsStreamSettings.toJsonArray(this.certs),
|
||||||
alpn: this.alpn,
|
alpn: this.alpn,
|
||||||
settings: this.settings,
|
settings: this.settings,
|
||||||
|
@ -708,7 +723,7 @@ class RealityStreamSettings extends XrayCommonClass {
|
||||||
minClient = '',
|
minClient = '',
|
||||||
maxClient = '',
|
maxClient = '',
|
||||||
maxTimediff = 0,
|
maxTimediff = 0,
|
||||||
shortIds = RandomUtil.randomShortId(8),
|
shortIds = RandomUtil.randomShortId(),
|
||||||
settings= new RealityStreamSettings.Settings()
|
settings= new RealityStreamSettings.Settings()
|
||||||
){
|
){
|
||||||
super();
|
super();
|
||||||
|
@ -1586,7 +1601,6 @@ Inbound.Settings = class extends XrayCommonClass {
|
||||||
case Protocols.TROJAN: return new Inbound.TrojanSettings(protocol);
|
case Protocols.TROJAN: return new Inbound.TrojanSettings(protocol);
|
||||||
case Protocols.SHADOWSOCKS: return new Inbound.ShadowsocksSettings(protocol);
|
case Protocols.SHADOWSOCKS: return new Inbound.ShadowsocksSettings(protocol);
|
||||||
case Protocols.DOKODEMO: return new Inbound.DokodemoSettings(protocol);
|
case Protocols.DOKODEMO: return new Inbound.DokodemoSettings(protocol);
|
||||||
case Protocols.MTPROTO: return new Inbound.MtprotoSettings(protocol);
|
|
||||||
case Protocols.SOCKS: return new Inbound.SocksSettings(protocol);
|
case Protocols.SOCKS: return new Inbound.SocksSettings(protocol);
|
||||||
case Protocols.HTTP: return new Inbound.HttpSettings(protocol);
|
case Protocols.HTTP: return new Inbound.HttpSettings(protocol);
|
||||||
default: return null;
|
default: return null;
|
||||||
|
@ -1600,7 +1614,6 @@ Inbound.Settings = class extends XrayCommonClass {
|
||||||
case Protocols.TROJAN: return Inbound.TrojanSettings.fromJson(json);
|
case Protocols.TROJAN: return Inbound.TrojanSettings.fromJson(json);
|
||||||
case Protocols.SHADOWSOCKS: return Inbound.ShadowsocksSettings.fromJson(json);
|
case Protocols.SHADOWSOCKS: return Inbound.ShadowsocksSettings.fromJson(json);
|
||||||
case Protocols.DOKODEMO: return Inbound.DokodemoSettings.fromJson(json);
|
case Protocols.DOKODEMO: return Inbound.DokodemoSettings.fromJson(json);
|
||||||
case Protocols.MTPROTO: return Inbound.MtprotoSettings.fromJson(json);
|
|
||||||
case Protocols.SOCKS: return Inbound.SocksSettings.fromJson(json);
|
case Protocols.SOCKS: return Inbound.SocksSettings.fromJson(json);
|
||||||
case Protocols.HTTP: return Inbound.HttpSettings.fromJson(json);
|
case Protocols.HTTP: return Inbound.HttpSettings.fromJson(json);
|
||||||
default: return null;
|
default: return null;
|
||||||
|
@ -1655,7 +1668,7 @@ Inbound.VmessSettings = class extends Inbound.Settings {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Inbound.VmessSettings.Vmess = class extends XrayCommonClass {
|
Inbound.VmessSettings.Vmess = class extends XrayCommonClass {
|
||||||
constructor(id=RandomUtil.randomUUID(), alterId=0, email=RandomUtil.randomText(8),limitIp=0, totalGB=0, expiryTime=0, enable=true, tgId='', subId=RandomUtil.randomText(16)) {
|
constructor(id=RandomUtil.randomUUID(), alterId=0, email=RandomUtil.randomLowerAndNum(8),limitIp=0, totalGB=0, expiryTime=0, enable=true, tgId='', subId=RandomUtil.randomLowerAndNum(16)) {
|
||||||
super();
|
super();
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.alterId = alterId;
|
this.alterId = alterId;
|
||||||
|
@ -1747,7 +1760,7 @@ Inbound.VLESSSettings = class extends Inbound.Settings {
|
||||||
|
|
||||||
};
|
};
|
||||||
Inbound.VLESSSettings.VLESS = class extends XrayCommonClass {
|
Inbound.VLESSSettings.VLESS = class extends XrayCommonClass {
|
||||||
constructor(id=RandomUtil.randomUUID(), flow='', email=RandomUtil.randomText(8),limitIp=0, totalGB=0, expiryTime=0, enable=true, tgId='', subId=RandomUtil.randomText(16)) {
|
constructor(id=RandomUtil.randomUUID(), flow='', email=RandomUtil.randomLowerAndNum(8),limitIp=0, totalGB=0, expiryTime=0, enable=true, tgId='', subId=RandomUtil.randomLowerAndNum(16)) {
|
||||||
super();
|
super();
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.flow = flow;
|
this.flow = flow;
|
||||||
|
@ -1870,7 +1883,7 @@ Inbound.TrojanSettings = class extends Inbound.Settings {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Inbound.TrojanSettings.Trojan = class extends XrayCommonClass {
|
Inbound.TrojanSettings.Trojan = class extends XrayCommonClass {
|
||||||
constructor(password=RandomUtil.randomSeq(10), flow='', email=RandomUtil.randomText(8),limitIp=0, totalGB=0, expiryTime=0, enable=true, tgId='', subId=RandomUtil.randomText(16)) {
|
constructor(password=RandomUtil.randomSeq(10), flow='', email=RandomUtil.randomLowerAndNum(8),limitIp=0, totalGB=0, expiryTime=0, enable=true, tgId='', subId=RandomUtil.randomLowerAndNum(16)) {
|
||||||
super();
|
super();
|
||||||
this.password = password;
|
this.password = password;
|
||||||
this.flow = flow;
|
this.flow = flow;
|
||||||
|
@ -2012,7 +2025,7 @@ Inbound.ShadowsocksSettings = class extends Inbound.Settings {
|
||||||
};
|
};
|
||||||
|
|
||||||
Inbound.ShadowsocksSettings.Shadowsocks = class extends XrayCommonClass {
|
Inbound.ShadowsocksSettings.Shadowsocks = class extends XrayCommonClass {
|
||||||
constructor(password=RandomUtil.randomShadowsocksPassword(), email=RandomUtil.randomText(8),limitIp=0, totalGB=0, expiryTime=0, enable=true, tgId='', subId=RandomUtil.randomText(16)) {
|
constructor(password=RandomUtil.randomShadowsocksPassword(), email=RandomUtil.randomLowerAndNum(8),limitIp=0, totalGB=0, expiryTime=0, enable=true, tgId='', subId=RandomUtil.randomLowerAndNum(16)) {
|
||||||
super();
|
super();
|
||||||
this.password = password;
|
this.password = password;
|
||||||
this.email = email;
|
this.email = email;
|
||||||
|
@ -2106,36 +2119,6 @@ Inbound.DokodemoSettings = class extends Inbound.Settings {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Inbound.MtprotoSettings = class extends Inbound.Settings {
|
|
||||||
constructor(protocol, users=[new Inbound.MtprotoSettings.MtUser()]) {
|
|
||||||
super(protocol);
|
|
||||||
this.users = users;
|
|
||||||
}
|
|
||||||
|
|
||||||
static fromJson(json={}) {
|
|
||||||
return new Inbound.MtprotoSettings(
|
|
||||||
Protocols.MTPROTO,
|
|
||||||
json.users.map(user => Inbound.MtprotoSettings.MtUser.fromJson(user)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
toJson() {
|
|
||||||
return {
|
|
||||||
users: XrayCommonClass.toJsonArray(this.users),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Inbound.MtprotoSettings.MtUser = class extends XrayCommonClass {
|
|
||||||
constructor(secret=RandomUtil.randomMTSecret()) {
|
|
||||||
super();
|
|
||||||
this.secret = secret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static fromJson(json={}) {
|
|
||||||
return new Inbound.MtprotoSettings.MtUser(json.secret);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Inbound.SocksSettings = class extends Inbound.Settings {
|
Inbound.SocksSettings = class extends Inbound.Settings {
|
||||||
constructor(protocol, auth='password', accounts=[new Inbound.SocksSettings.SocksAccount()], udp=false, ip='127.0.0.1') {
|
constructor(protocol, auth='password', accounts=[new Inbound.SocksSettings.SocksAccount()], udp=false, ip='127.0.0.1') {
|
||||||
super(protocol);
|
super(protocol);
|
||||||
|
|
|
@ -94,41 +94,30 @@ class RandomUtil {
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
static randomShortId(count) {
|
static randomShortId() {
|
||||||
let str = '';
|
let str = '';
|
||||||
for (let i = 0; i < count; ++i) {
|
for (let i = 0; i < 8; ++i) {
|
||||||
str += seq[this.randomInt(16)];
|
str += seq[this.randomInt(16)];
|
||||||
}
|
}
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
static randomText(len) {
|
static randomLowerAndNum(len) {
|
||||||
let str = '';
|
let str = '';
|
||||||
for (let i = 0; i < len; i++) {
|
for (let i = 0; i < len; ++i) {
|
||||||
str += seq[this.randomInt(36)];
|
str += seq[this.randomInt(36)];
|
||||||
}
|
}
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
static randomMTSecret() {
|
|
||||||
let str = '';
|
|
||||||
for (let i = 0; i < 32; ++i) {
|
|
||||||
let index = this.randomInt(16);
|
|
||||||
if (index <= 9) {
|
|
||||||
str += index;
|
|
||||||
} else {
|
|
||||||
str += seq[index - 10];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
static randomUUID() {
|
static randomUUID() {
|
||||||
let d = new Date().getTime();
|
const template = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';
|
||||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
return template.replace(/[xy]/g, function (c) {
|
||||||
let r = (d + Math.random() * 16) % 16 | 0;
|
const randomValues = new Uint8Array(1);
|
||||||
d = Math.floor(d / 16);
|
crypto.getRandomValues(randomValues);
|
||||||
return (c === 'x' ? r : (r & 0x7 | 0x8)).toString(16);
|
let randomValue = randomValues[0] % 16;
|
||||||
|
let calculatedValue = (c === 'x') ? randomValue : (randomValue & 0x3 | 0x8);
|
||||||
|
return calculatedValue.toString(16);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
</template>
|
</template>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</span>
|
</span>
|
||||||
<a-icon @click="client.email = RandomUtil.randomText(8)" type="sync"> </a-icon>
|
<a-icon @click="client.email = RandomUtil.randomLowerAndNum(8)" type="sync"> </a-icon>
|
||||||
<a-input v-model.trim="client.email" style="width: 200px;"></a-input>
|
<a-input v-model.trim="client.email" style="width: 200px;"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="Password" v-if="inbound.protocol === Protocols.TROJAN || inbound.protocol === Protocols.SHADOWSOCKS">
|
<a-form-item label="Password" v-if="inbound.protocol === Protocols.TROJAN || inbound.protocol === Protocols.SHADOWSOCKS">
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
<a-icon type="question-circle" theme="filled"></a-icon>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</span>
|
</span>
|
||||||
<a-icon @click="client.subId = RandomUtil.randomText(16)" type="sync"> </a-icon>
|
<a-icon @click="client.subId = RandomUtil.randomLowerAndNum(16)" type="sync"> </a-icon>
|
||||||
<a-input v-model.trim="client.subId" style="width: 150px;"></a-input>
|
<a-input v-model.trim="client.subId" style="width: 150px;"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item v-if="client.email && app.tgBotEnable" >
|
<a-form-item v-if="client.email && app.tgBotEnable" >
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
</template>
|
</template>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</span>
|
</span>
|
||||||
<a-icon @click="client.email = RandomUtil.randomText(8)" type="sync"> </a-icon>
|
<a-icon @click="client.email = RandomUtil.randomLowerAndNum(8)" type="sync"> </a-icon>
|
||||||
<a-input v-model.trim="client.email" style="width: 200px;"></a-input>
|
<a-input v-model.trim="client.email" style="width: 200px;"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="Password">
|
<a-form-item label="Password">
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
<a-icon type="question-circle" theme="filled"></a-icon>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</span>
|
</span>
|
||||||
<a-icon @click="client.subId = RandomUtil.randomText(16)" type="sync"> </a-icon>
|
<a-icon @click="client.subId = RandomUtil.randomLowerAndNum(16)" type="sync"> </a-icon>
|
||||||
<a-input v-model.trim="client.subId" style="width: 150px;"></a-input>
|
<a-input v-model.trim="client.subId" style="width: 150px;"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item v-if="client.email && app.tgBotEnable">
|
<a-form-item v-if="client.email && app.tgBotEnable">
|
||||||
|
@ -112,6 +112,7 @@
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label='{{ i18n "password" }}'>
|
<a-form-item label='{{ i18n "password" }}'>
|
||||||
|
<a-icon @click="inbound.settings.password = RandomUtil.randomShadowsocksPassword()" type="sync"> </a-icon>
|
||||||
<a-input v-model.trim="inbound.settings.password" style="width: 250px;"></a-input>
|
<a-input v-model.trim="inbound.settings.password" style="width: 250px;"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label='{{ i18n "pages.inbounds.network" }}'>
|
<a-form-item label='{{ i18n "pages.inbounds.network" }}'>
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
</template>
|
</template>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</span>
|
</span>
|
||||||
<a-icon @click="client.email = RandomUtil.randomText(8)" type="sync"> </a-icon>
|
<a-icon @click="client.email = RandomUtil.randomLowerAndNum(8)" type="sync"> </a-icon>
|
||||||
<a-input v-model.trim="client.email" style="width: 200px;"></a-input>
|
<a-input v-model.trim="client.email" style="width: 200px;"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="Password">
|
<a-form-item label="Password">
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
<a-icon type="question-circle" theme="filled"></a-icon>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</span>
|
</span>
|
||||||
<a-icon @click="client.subId = RandomUtil.randomText(16)" type="sync"> </a-icon>
|
<a-icon @click="client.subId = RandomUtil.randomLowerAndNum(16)" type="sync"> </a-icon>
|
||||||
<a-input v-model.trim="client.subId" style="width: 150px;"></a-input>
|
<a-input v-model.trim="client.subId" style="width: 150px;"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item v-if="client.email && app.tgBotEnable">
|
<a-form-item v-if="client.email && app.tgBotEnable">
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
</template>
|
</template>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</span>
|
</span>
|
||||||
<a-icon @click="client.email = RandomUtil.randomText(8)" type="sync"> </a-icon>
|
<a-icon @click="client.email = RandomUtil.randomLowerAndNum(8)" type="sync"> </a-icon>
|
||||||
<a-input v-model.trim="client.email" style="width: 200px;"></a-input>
|
<a-input v-model.trim="client.email" style="width: 200px;"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="ID">
|
<a-form-item label="ID">
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
<a-icon type="question-circle" theme="filled"></a-icon>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</span>
|
</span>
|
||||||
<a-icon @click="client.subId = RandomUtil.randomText(16)" type="sync"> </a-icon>
|
<a-icon @click="client.subId = RandomUtil.randomLowerAndNum(16)" type="sync"> </a-icon>
|
||||||
<a-input v-model.trim="client.subId" style="width: 150px;"></a-input>
|
<a-input v-model.trim="client.subId" style="width: 150px;"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item v-if="client.email && app.tgBotEnable">
|
<a-form-item v-if="client.email && app.tgBotEnable">
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
</template>
|
</template>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</span>
|
</span>
|
||||||
<a-icon @click="client.email = RandomUtil.randomText(8)" type="sync"> </a-icon>
|
<a-icon @click="client.email = RandomUtil.randomLowerAndNum(8)" type="sync"> </a-icon>
|
||||||
<a-input v-model.trim="client.email" style="width: 200px;"></a-input>
|
<a-input v-model.trim="client.email" style="width: 200px;"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<br>
|
<br>
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
<a-icon type="question-circle" theme="filled"></a-icon>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</span>
|
</span>
|
||||||
<a-icon @click="client.subId = RandomUtil.randomText(16)" type="sync"> </a-icon>
|
<a-icon @click="client.subId = RandomUtil.randomLowerAndNum(16)" type="sync"> </a-icon>
|
||||||
<a-input v-model.trim="client.subId" style="width: 150px;"></a-input>
|
<a-input v-model.trim="client.subId" style="width: 150px;"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item v-if="client.email && app.tgBotEnable">
|
<a-form-item v-if="client.email && app.tgBotEnable">
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
{{define "form/streamGRPC"}}
|
{{define "form/streamGRPC"}}
|
||||||
<a-form layout="inline">
|
<a-form layout="inline">
|
||||||
|
<a-form-item label="AcceptProxyProtocol">
|
||||||
|
<a-switch v-model="inbound.stream.grpc.sockopt.acceptProxyProtocol"></a-switch>
|
||||||
|
</a-form-item>
|
||||||
|
<br>
|
||||||
<a-form-item label="ServiceName">
|
<a-form-item label="ServiceName">
|
||||||
<a-input v-model.trim="inbound.stream.grpc.serviceName"></a-input>
|
<a-input v-model.trim="inbound.stream.grpc.serviceName"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
{{define "form/streamHTTP"}}
|
{{define "form/streamHTTP"}}
|
||||||
<a-form layout="inline">
|
<a-form layout="inline">
|
||||||
|
<a-form-item label="AcceptProxyProtocol">
|
||||||
|
<a-switch v-model="inbound.stream.http.sockopt.acceptProxyProtocol"></a-switch>
|
||||||
|
</a-form-item>
|
||||||
|
<br>
|
||||||
<a-form-item label='{{ i18n "path" }}'>
|
<a-form-item label='{{ i18n "path" }}'>
|
||||||
<a-input v-model.trim="inbound.stream.http.path"></a-input>
|
<a-input v-model.trim="inbound.stream.http.path"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
<a-form-item label="AcceptProxyProtocol">
|
<a-form-item label="AcceptProxyProtocol">
|
||||||
<a-switch v-model="inbound.stream.ws.acceptProxyProtocol"></a-switch>
|
<a-switch v-model="inbound.stream.ws.acceptProxyProtocol"></a-switch>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
<br>
|
||||||
<a-form layout="inline">
|
|
||||||
<a-form-item label='{{ i18n "path" }}'>
|
<a-form-item label='{{ i18n "path" }}'>
|
||||||
<a-input v-model.trim="inbound.stream.ws.path"></a-input>
|
<a-input v-model.trim="inbound.stream.ws.path"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
<a-form v-if="inbound.tls" layout="inline">
|
<a-form v-if="inbound.tls" layout="inline">
|
||||||
<a-form-item label='Multi Domain'>
|
<a-form-item label='Multi Domain'>
|
||||||
<a-switch v-model="multiDomain"></a-switch>
|
<a-switch v-model="multiDomain"></a-switch>
|
||||||
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item v-if="multiDomain">
|
<a-form-item v-if="multiDomain">
|
||||||
<a-row>
|
<a-row>
|
||||||
|
@ -85,9 +84,14 @@
|
||||||
<a-checkbox v-for="key,value in ALPN_OPTION" :value="key">[[ value ]]</a-checkbox>
|
<a-checkbox v-for="key,value in ALPN_OPTION" :value="key">[[ value ]]</a-checkbox>
|
||||||
</a-checkbox-group>
|
</a-checkbox-group>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<br>
|
||||||
<a-form-item label="Allow insecure">
|
<a-form-item label="Allow insecure">
|
||||||
<a-switch v-model="inbound.stream.tls.settings.allowInsecure"></a-switch>
|
<a-switch v-model="inbound.stream.tls.settings.allowInsecure"></a-switch>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<br>
|
||||||
|
<a-form-item label="Reject Unknown SNI">
|
||||||
|
<a-switch v-model="inbound.stream.tls.rejectUnknownSni"></a-switch>
|
||||||
|
</a-form-item>
|
||||||
<template v-for="cert,index in inbound.stream.tls.certs">
|
<template v-for="cert,index in inbound.stream.tls.certs">
|
||||||
<a-form-item label='{{ i18n "certificate" }}'>
|
<a-form-item label='{{ i18n "certificate" }}'>
|
||||||
<a-radio-group v-model="cert.useFile" button-style="solid">
|
<a-radio-group v-model="cert.useFile" button-style="solid">
|
||||||
|
@ -187,7 +191,7 @@
|
||||||
<a-input v-model.trim="inbound.stream.reality.serverNames" style="width: 300px"></a-input>
|
<a-input v-model.trim="inbound.stream.reality.serverNames" style="width: 300px"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="ShortIds">
|
<a-form-item label="ShortIds">
|
||||||
<a-icon @click="inbound.stream.reality.shortIds = RandomUtil.randomShortId(8)" type="sync"> </a-icon>
|
<a-icon @click="inbound.stream.reality.shortIds = RandomUtil.randomShortId()" type="sync"> </a-icon>
|
||||||
<a-input v-model.trim="inbound.stream.reality.shortIds" style="width: 150px;"></a-input>
|
<a-input v-model.trim="inbound.stream.reality.shortIds" style="width: 150px;"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<br>
|
<br>
|
||||||
|
|
Loading…
Reference in a new issue