diff options
Diffstat (limited to 'web/assets/js/model')
| -rw-r--r-- | web/assets/js/model/models.js | 185 | ||||
| -rw-r--r-- | web/assets/js/model/xray.js | 1819 |
2 files changed, 2004 insertions, 0 deletions
diff --git a/web/assets/js/model/models.js b/web/assets/js/model/models.js new file mode 100644 index 00000000..768bf4de --- /dev/null +++ b/web/assets/js/model/models.js @@ -0,0 +1,185 @@ +class User { + + constructor() { + this.username = ""; + this.password = ""; + } +} + +class Msg { + + constructor(success, msg, obj) { + this.success = false; + this.msg = ""; + this.obj = null; + + if (success != null) { + this.success = success; + } + if (msg != null) { + this.msg = msg; + } + if (obj != null) { + this.obj = obj; + } + } +} + +class DBInbound { + + constructor(data) { + this.id = 0; + this.userId = 0; + this.up = 0; + this.down = 0; + this.total = 0; + this.remark = ""; + this.enable = true; + this.expiryTime = 0; + + this.listen = ""; + this.port = 0; + this.protocol = ""; + this.settings = ""; + this.streamSettings = ""; + this.tag = ""; + this.sniffing = ""; + this.clientStats = "" + if (data == null) { + return; + } + ObjectUtil.cloneProps(this, data); + } + + get totalGB() { + return toFixed(this.total / ONE_GB, 2); + } + + set totalGB(gb) { + this.total = toFixed(gb * ONE_GB, 0); + } + + get isVMess() { + return this.protocol === Protocols.VMESS; + } + + get isVLess() { + return this.protocol === Protocols.VLESS; + } + + get isTrojan() { + return this.protocol === Protocols.TROJAN; + } + + get isSS() { + return this.protocol === Protocols.SHADOWSOCKS; + } + + get isSocks() { + return this.protocol === Protocols.SOCKS; + } + + get isHTTP() { + return this.protocol === Protocols.HTTP; + } + + get address() { + let address = location.hostname; + if (!ObjectUtil.isEmpty(this.listen) && this.listen !== "0.0.0.0") { + address = this.listen; + } + return address; + } + + get _expiryTime() { + if (this.expiryTime === 0) { + return null; + } + return moment(this.expiryTime); + } + + set _expiryTime(t) { + if (t == null) { + this.expiryTime = 0; + } else { + this.expiryTime = t.valueOf(); + } + } + + get isExpiry() { + return this.expiryTime < new Date().getTime(); + } + + toInbound() { + let settings = {}; + if (!ObjectUtil.isEmpty(this.settings)) { + settings = JSON.parse(this.settings); + } + + let streamSettings = {}; + if (!ObjectUtil.isEmpty(this.streamSettings)) { + streamSettings = JSON.parse(this.streamSettings); + } + + let sniffing = {}; + if (!ObjectUtil.isEmpty(this.sniffing)) { + sniffing = JSON.parse(this.sniffing); + } + + const config = { + port: this.port, + listen: this.listen, + protocol: this.protocol, + settings: settings, + streamSettings: streamSettings, + tag: this.tag, + sniffing: sniffing, + clientStats: this.clientStats, + }; + return Inbound.fromJson(config); + } + + hasLink() { + switch (this.protocol) { + case Protocols.VMESS: + case Protocols.VLESS: + case Protocols.TROJAN: + case Protocols.SHADOWSOCKS: + return true; + default: + return false; + } + } + + genLink() { + const inbound = this.toInbound(); + return inbound.genLink(this.address, this.remark); + } +} + +class AllSetting { + + constructor(data) { + this.webListen = ""; + this.webPort = 54321; + this.webCertFile = ""; + this.webKeyFile = ""; + this.webBasePath = "/"; + this.tgBotEnable = false; + this.tgBotToken = ""; + this.tgBotChatId = 0; + this.tgRunTime = ""; + this.xrayTemplateConfig = ""; + + this.timeLocation = "Asia/Shanghai"; + + if (data == null) { + return + } + ObjectUtil.cloneProps(this, data); + } + + equals(other) { + return ObjectUtil.equals(this, other); + } +}
\ No newline at end of file diff --git a/web/assets/js/model/xray.js b/web/assets/js/model/xray.js new file mode 100644 index 00000000..78af69b6 --- /dev/null +++ b/web/assets/js/model/xray.js @@ -0,0 +1,1819 @@ +const Protocols = { + VMESS: 'vmess', + VLESS: 'vless', + TROJAN: 'trojan', + SHADOWSOCKS: 'shadowsocks', + DOKODEMO: 'dokodemo-door', + MTPROTO: 'mtproto', + SOCKS: 'socks', + HTTP: 'http', +}; + +const VmessMethods = { + AES_128_GCM: 'aes-128-gcm', + CHACHA20_POLY1305: 'chacha20-poly1305', + AUTO: 'auto', + NONE: 'none', +}; + +const SSMethods = { + // AES_256_CFB: 'aes-256-cfb', + // AES_128_CFB: 'aes-128-cfb', + // CHACHA20: 'chacha20', + // CHACHA20_IETF: 'chacha20-ietf', + CHACHA20_POLY1305: 'chacha20-poly1305', + AES_256_GCM: 'aes-256-gcm', + AES_128_GCM: 'aes-128-gcm', + BLAKE3_AES_128_GCM: '2022-blake3-aes-128-gcm', + BLAKE3_AES_256_GCM: '2022-blake3-aes-256-gcm', + BLAKE3_CHACHA20_POLY1305: '2022-blake3-chacha20-poly1305', +}; + +const RULE_IP = { + PRIVATE: 'geoip:private', + CN: 'geoip:cn', +}; + +const RULE_DOMAIN = { + ADS: 'geosite:category-ads', + ADS_ALL: 'geosite:category-ads-all', + CN: 'geosite:cn', + GOOGLE: 'geosite:google', + FACEBOOK: 'geosite:facebook', + SPEEDTEST: 'geosite:speedtest', +}; + +const XTLS_FLOW_CONTROL = { + ORIGIN: "xtls-rprx-origin", + DIRECT: "xtls-rprx-direct", +}; + +const TLS_FLOW_CONTROL = { + VISION: "xtls-rprx-vision", +}; + +const TLS_VERSION_OPTION = { + TLS10: "1.0", + TLS11: "1.1", + TLS12: "1.2", + TLS13: "1.3", +} + +const TLS_CIPHER_OPTION = { + RSA_AES_128_CBC: "TLS_RSA_WITH_AES_128_CBC_SHA", + RSA_AES_256_CBC: "TLS_RSA_WITH_AES_256_CBC_SHA", + RSA_AES_128_GCM: "TLS_RSA_WITH_AES_128_GCM_SHA256", + RSA_AES_256_GCM: "TLS_RSA_WITH_AES_256_GCM_SHA384", + AES_128_GCM: "TLS_AES_128_GCM_SHA256", + AES_256_GCM: "TLS_AES_256_GCM_SHA384", + CHACHA20_POLY1305: "TLS_CHACHA20_POLY1305_SHA256", + ECDHE_ECDSA_AES_128_CBC: "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + ECDHE_ECDSA_AES_256_CBC: "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + ECDHE_RSA_AES_128_CBC: "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + ECDHE_RSA_AES_256_CBC: "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + ECDHE_ECDSA_AES_128_GCM: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + ECDHE_ECDSA_AES_256_GCM: "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + ECDHE_RSA_AES_128_GCM: "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + ECDHE_RSA_AES_256_GCM: "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + ECDHE_ECDSA_CHACHA20_POLY1305: "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", + ECDHE_RSA_CHACHA20_POLY1305: "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", +}; + +const UTLS_FINGERPRINT = { + UTLS_CHROME: "chrome", + UTLS_FIREFOX: "firefox", + UTLS_SAFARI: "safari", + UTLS_IOS: "ios", + UTLS_android: "android", + UTLS_EDGE: "edge", + UTLS_360: "360", + UTLS_QQ: "qq", + UTLS_RANDOM: "random", + UTLS_RANDOMIZED: "randomized", +}; + +Object.freeze(Protocols); +Object.freeze(VmessMethods); +Object.freeze(SSMethods); +Object.freeze(RULE_IP); +Object.freeze(RULE_DOMAIN); +Object.freeze(XTLS_FLOW_CONTROL); +Object.freeze(TLS_FLOW_CONTROL); +Object.freeze(TLS_VERSION_OPTION); +Object.freeze(TLS_CIPHER_OPTION); + +class XrayCommonClass { + + static toJsonArray(arr) { + return arr.map(obj => obj.toJson()); + } + + static fromJson() { + return new XrayCommonClass(); + } + + toJson() { + return this; + } + + toString(format=true) { + return format ? JSON.stringify(this.toJson(), null, 2) : JSON.stringify(this.toJson()); + } + + static toHeaders(v2Headers) { + let newHeaders = []; + if (v2Headers) { + Object.keys(v2Headers).forEach(key => { + let values = v2Headers[key]; + if (typeof(values) === 'string') { + newHeaders.push({ name: key, value: values }); + } else { + for (let i = 0; i < values.length; ++i) { + newHeaders.push({ name: key, value: values[i] }); + } + } + }); + } + return newHeaders; + } + + static toV2Headers(headers, arr=true) { + let v2Headers = {}; + for (let i = 0; i < headers.length; ++i) { + let name = headers[i].name; + let value = headers[i].value; + if (ObjectUtil.isEmpty(name) || ObjectUtil.isEmpty(value)) { + continue; + } + if (!(name in v2Headers)) { + v2Headers[name] = arr ? [value] : value; + } else { + if (arr) { + v2Headers[name].push(value); + } else { + v2Headers[name] = value; + } + } + } + return v2Headers; + } +} + +class TcpStreamSettings extends XrayCommonClass { + constructor( + type = 'none', + acceptProxyProtocol = false, + request = new TcpStreamSettings.TcpRequest(), + response = new TcpStreamSettings.TcpResponse(), + ) { + super(); + this.type = type; + this.request = request; + this.response = response; + this.acceptProxyProtocol = acceptProxyProtocol; + } + + static fromJson(json = {}) { + let header = json.header; + if (!header) { + header = {}; + } + return new TcpStreamSettings( + header.type, + json.acceptProxyProtocol, + TcpStreamSettings.TcpRequest.fromJson(header.request), + TcpStreamSettings.TcpResponse.fromJson(header.response), + ); + } + + toJson() { + return { + header: { + type: this.type, + request: this.type === 'http' ? this.request.toJson() : undefined, + response: this.type === 'http' ? this.response.toJson() : undefined, + }, + acceptProxyProtocol: this.acceptProxyProtocol, + }; + } +} + +TcpStreamSettings.TcpRequest = class extends XrayCommonClass { + constructor(version = '1.1', + method = 'GET', + path = ['/'], + headers = [], + ) { + super(); + this.version = version; + this.method = method; + this.path = path.length === 0 ? ['/'] : path; + this.headers = headers; + } + + addPath(path) { + this.path.push(path); + } + + removePath(index) { + this.path.splice(index, 1); + } + + addHeader(name, value) { + this.headers.push({ name: name, value: value }); + } + + getHeader(name) { + for (const header of this.headers) { + if (header.name.toLowerCase() === name.toLowerCase()) { + return header.value; + } + } + return null; + } + + removeHeader(index) { + this.headers.splice(index, 1); + } + + static fromJson(json = {}) { + return new TcpStreamSettings.TcpRequest( + json.version, + json.method, + json.path, + XrayCommonClass.toHeaders(json.headers), + ); + } + + toJson() { + return { + method: this.method, + path: ObjectUtil.clone(this.path), + headers: XrayCommonClass.toV2Headers(this.headers), + }; + } +}; + +TcpStreamSettings.TcpResponse = class extends XrayCommonClass { + constructor(version = '1.1', + status = '200', + reason = 'OK', + headers = [], + ) { + super(); + this.version = version; + this.status = status; + this.reason = reason; + this.headers = headers; + } + + addHeader(name, value) { + this.headers.push({ name: name, value: value }); + } + + removeHeader(index) { + this.headers.splice(index, 1); + } + + static fromJson(json = {}) { + return new TcpStreamSettings.TcpResponse( + json.version, + json.status, + json.reason, + XrayCommonClass.toHeaders(json.headers), + ); + } + + toJson() { + return { + version: this.version, + status: this.status, + reason: this.reason, + headers: XrayCommonClass.toV2Headers(this.headers), + }; + } +}; + +class KcpStreamSettings extends XrayCommonClass { + constructor(mtu=1350, tti=20, + uplinkCapacity=5, + downlinkCapacity=20, + congestion=false, + readBufferSize=2, + writeBufferSize=2, + type='none', + seed=RandomUtil.randomSeq(10), + ) { + super(); + this.mtu = mtu; + this.tti = tti; + this.upCap = uplinkCapacity; + this.downCap = downlinkCapacity; + this.congestion = congestion; + this.readBuffer = readBufferSize; + this.writeBuffer = writeBufferSize; + this.type = type; + this.seed = seed; + } + + static fromJson(json={}) { + return new KcpStreamSettings( + json.mtu, + json.tti, + json.uplinkCapacity, + json.downlinkCapacity, + json.congestion, + json.readBufferSize, + json.writeBufferSize, + ObjectUtil.isEmpty(json.header) ? 'none' : json.header.type, + json.seed, + ); + } + + toJson() { + return { + mtu: this.mtu, + tti: this.tti, + uplinkCapacity: this.upCap, + downlinkCapacity: this.downCap, + congestion: this.congestion, + readBufferSize: this.readBuffer, + writeBufferSize: this.writeBuffer, + header: { + type: this.type, + }, + seed: this.seed, + }; + } +} + +class WsStreamSettings extends XrayCommonClass { + constructor(acceptProxyProtocol=false, path='/', headers=[]) { + super(); + this.acceptProxyProtocol = acceptProxyProtocol; + this.path = path; + this.headers = headers; + } + + addHeader(name, value) { + this.headers.push({ name: name, value: value }); + } + + getHeader(name) { + for (const header of this.headers) { + if (header.name.toLowerCase() === name.toLowerCase()) { + return header.value; + } + } + return null; + } + + removeHeader(index) { + this.headers.splice(index, 1); + } + + static fromJson(json={}) { + return new WsStreamSettings( + json.acceptProxyProtocol, + json.path, + XrayCommonClass.toHeaders(json.headers), + ); + } + + toJson() { + return { + acceptProxyProtocol: this.acceptProxyProtocol, + path: this.path, + headers: XrayCommonClass.toV2Headers(this.headers, false), + }; + } +} + +class HttpStreamSettings extends XrayCommonClass { + constructor(path='/', host=['']) { + super(); + this.path = path; + this.host = host.length === 0 ? [''] : host; + } + + addHost(host) { + this.host.push(host); + } + + removeHost(index) { + this.host.splice(index, 1); + } + + static fromJson(json={}) { + return new HttpStreamSettings(json.path, json.host); + } + + toJson() { + let host = []; + for (let i = 0; i < this.host.length; ++i) { + if (!ObjectUtil.isEmpty(this.host[i])) { + host.push(this.host[i]); + } + } + return { + path: this.path, + host: host, + } + } +} + +class QuicStreamSettings extends XrayCommonClass { + constructor(security=VmessMethods.NONE, + key='', type='none') { + super(); + this.security = security; + this.key = key; + this.type = type; + } + + static fromJson(json={}) { + return new QuicStreamSettings( + json.security, + json.key, + json.header ? json.header.type : 'none', + ); + } + + toJson() { + return { + security: this.security, + key: this.key, + header: { + type: this.type, + } + } + } +} + +class GrpcStreamSettings extends XrayCommonClass { + constructor(serviceName="") { + super(); + this.serviceName = serviceName; + } + + static fromJson(json={}) { + return new GrpcStreamSettings(json.serviceName); + } + + toJson() { + return { + serviceName: this.serviceName, + } + } +} + +class TlsStreamSettings extends XrayCommonClass { + constructor(serverName = '', minVersion = TLS_VERSION_OPTION.TLS12, maxVersion = TLS_VERSION_OPTION.TLS13, + cipherSuites = '', + certificates = [new TlsStreamSettings.Cert()], alpn = ["h2", "http/1.1"]) { + super(); + this.server = serverName; + this.minVersion = minVersion; + this.maxVersion = maxVersion; + this.cipherSuites = cipherSuites; + this.certs = certificates; + this.alpn = alpn; + } + + addCert(cert) { + this.certs.push(cert); + } + + removeCert(index) { + this.certs.splice(index, 1); + } + + static fromJson(json={}) { + let certs; + if (!ObjectUtil.isEmpty(json.certificates)) { + certs = json.certificates.map(cert => TlsStreamSettings.Cert.fromJson(cert)); + } + + return new TlsStreamSettings( + json.serverName, + json.minVersion, + json.maxVersion, + json.cipherSuites, + certs, + json.alpn, + ); + } + + toJson() { + return { + serverName: this.server, + minVersion: this.minVersion, + maxVersion: this.maxVersion, + cipherSuites: this.cipherSuites, + certificates: TlsStreamSettings.toJsonArray(this.certs), + alpn: this.alpn + }; + } +} + +TlsStreamSettings.Cert = class extends XrayCommonClass { + constructor(useFile=true, certificateFile='', keyFile='', certificate='', key='') { + super(); + this.useFile = useFile; + this.certFile = certificateFile; + this.keyFile = keyFile; + this.cert = certificate instanceof Array ? certificate.join('\n') : certificate; + this.key = key instanceof Array ? key.join('\n') : key; + } + + static fromJson(json={}) { + if ('certificateFile' in json && 'keyFile' in json) { + return new TlsStreamSettings.Cert( + true, + json.certificateFile, + json.keyFile, + ); + } else { + return new TlsStreamSettings.Cert( + false, '', '', + json.certificate.join('\n'), + json.key.join('\n'), + ); + } + } + + toJson() { + if (this.useFile) { + return { + certificateFile: this.certFile, + keyFile: this.keyFile, + }; + } else { + return { + certificate: this.cert.split('\n'), + key: this.key.split('\n'), + }; + } + } +}; + +class StreamSettings extends XrayCommonClass { + constructor(network='tcp', + security='none', + tlsSettings=new TlsStreamSettings(), + tcpSettings=new TcpStreamSettings(), + kcpSettings=new KcpStreamSettings(), + wsSettings=new WsStreamSettings(), + httpSettings=new HttpStreamSettings(), + quicSettings=new QuicStreamSettings(), + grpcSettings=new GrpcStreamSettings(), + ) { + super(); + this.network = network; + this.security = security; + this.tls = tlsSettings; + this.tcp = tcpSettings; + this.kcp = kcpSettings; + this.ws = wsSettings; + this.http = httpSettings; + this.quic = quicSettings; + this.grpc = grpcSettings; + } + + get isTls() { + return this.security === 'tls'; + } + + set isTls(isTls) { + if (isTls) { + this.security = 'tls'; + } else { + this.security = 'none'; + } + } + + get isXTls() { + return this.security === "xtls"; + } + + set isXTls(isXTls) { + if (isXTls) { + this.security = 'xtls'; + } else { + this.security = 'none'; + } + } + + static fromJson(json={}) { + let tls; + if (json.security === "xtls") { + tls = TlsStreamSettings.fromJson(json.xtlsSettings); + } else { + tls = TlsStreamSettings.fromJson(json.tlsSettings); + } + return new StreamSettings( + json.network, + json.security, + tls, + TcpStreamSettings.fromJson(json.tcpSettings), + KcpStreamSettings.fromJson(json.kcpSettings), + WsStreamSettings.fromJson(json.wsSettings), + HttpStreamSettings.fromJson(json.httpSettings), + QuicStreamSettings.fromJson(json.quicSettings), + GrpcStreamSettings.fromJson(json.grpcSettings), + ); + } + + toJson() { + const network = this.network; + return { + network: network, + security: this.security, + tlsSettings: this.isTls ? this.tls.toJson() : undefined, + xtlsSettings: this.isXTls ? this.tls.toJson() : undefined, + tcpSettings: network === 'tcp' ? this.tcp.toJson() : undefined, + kcpSettings: network === 'kcp' ? this.kcp.toJson() : undefined, + wsSettings: network === 'ws' ? this.ws.toJson() : undefined, + httpSettings: network === 'http' ? this.http.toJson() : undefined, + quicSettings: network === 'quic' ? this.quic.toJson() : undefined, + grpcSettings: network === 'grpc' ? this.grpc.toJson() : undefined, + }; + } +} + +class Sniffing extends XrayCommonClass { + constructor(enabled=true, destOverride=['http', 'tls']) { + super(); + this.enabled = enabled; + this.destOverride = destOverride; + } + + static fromJson(json={}) { + let destOverride = ObjectUtil.clone(json.destOverride); + if (!ObjectUtil.isEmpty(destOverride) && !ObjectUtil.isArrEmpty(destOverride)) { + if (ObjectUtil.isEmpty(destOverride[0])) { + destOverride = ['http', 'tls']; + } + } + return new Sniffing( + !!json.enabled, + destOverride, + ); + } +} + +class Inbound extends XrayCommonClass { + constructor(port=RandomUtil.randomIntRange(10000, 60000), + listen='', + protocol=Protocols.VMESS, + settings=null, + streamSettings=new StreamSettings(), + tag='', + sniffing=new Sniffing(), + clientStats='', + ) { + super(); + this.port = port; + this.listen = listen; + this._protocol = protocol; + this.settings = ObjectUtil.isEmpty(settings) ? Inbound.Settings.getSettings(protocol) : settings; + this.stream = streamSettings; + this.tag = tag; + this.sniffing = sniffing; + this.clientStats = clientStats; + } + getClientStats() { + return this.clientStats; + } + + get protocol() { + return this._protocol; + } + + set protocol(protocol) { + this._protocol = protocol; + this.settings = Inbound.Settings.getSettings(protocol); + if (protocol === Protocols.TROJAN) { + this.tls = true; + } + } + get tls() { + return this.stream.security === 'tls'; + } + + set tls(isTls) { + if (isTls) { + this.stream.security = 'tls'; + } else { + this.stream.security = 'none'; + } + } + + get xtls() { + return this.stream.security === 'xtls'; + } + + set xtls(isXTls) { + if (isXTls) { + this.stream.security = 'xtls'; + } else { + this.stream.security = 'none'; + } + } + + get network() { + return this.stream.network; + } + + set network(network) { + this.stream.network = network; + } + + get isTcp() { + return this.network === "tcp"; + } + + get isWs() { + return this.network === "ws"; + } + + get isKcp() { + return this.network === "kcp"; + } + + get isQuic() { + return this.network === "quic" + } + + get isGrpc() { + return this.network === "grpc"; + } + + get isH2() { + return this.network === "http"; + } + + isInboundEmpty() { + if (this.protocol == Protocols.VMESS && this.settings.vmesses.length == 0) { + return true; + } else if (this.protocol == Protocols.VLESS && this.settings.vlesses.length == 0) { + return true; + } else if (this.protocol == Protocols.TROJAN && this.settings.trojans.length == 0) { + return true; + } else { + return false; + } + } + + // VMess & VLess + get uuid() { + switch (this.protocol) { + case Protocols.VMESS: + return this.settings.vmesses[0].id; + case Protocols.VLESS: + return this.settings.vlesses[0].id; + default: + return ""; + } + } + + // VLess & Trojan + get flow() { + switch (this.protocol) { + case Protocols.VLESS: + return this.settings.vlesses[0].flow; + case Protocols.TROJAN: + return this.settings.trojans[0].flow; + default: + return ""; + } + } + + // VMess + get alterId() { + switch (this.protocol) { + case Protocols.VMESS: + return this.settings.vmesses[0].alterId; + default: + return ""; + } + } + + // Socks & HTTP + get username() { + switch (this.protocol) { + case Protocols.SOCKS: + case Protocols.HTTP: + return this.settings.accounts[0].user; + default: + return ""; + } + } + + // Trojan & Shadowsocks & Socks & HTTP + get password() { + switch (this.protocol) { + case Protocols.TROJAN: + return this.settings.trojans[0].password; + case Protocols.SHADOWSOCKS: + return this.settings.password; + case Protocols.SOCKS: + case Protocols.HTTP: + return this.settings.accounts[0].pass; + default: + return ""; + } + } + + // Shadowsocks + get method() { + switch (this.protocol) { + case Protocols.SHADOWSOCKS: + return this.settings.method; + default: + return ""; + } + } + + get serverName() { + if (this.stream.isTls || this.stream.isXTls) { + return this.stream.tls.server; + } + return ""; + } + + get host() { + if (this.isTcp) { + return this.stream.tcp.request.getHeader("Host"); + } else if (this.isWs) { + return this.stream.ws.getHeader("Host"); + } else if (this.isH2) { + return this.stream.http.host[0]; + } + return null; + } + + get path() { + if (this.isTcp) { + return this.stream.tcp.request.path[0]; + } else if (this.isWs) { + return this.stream.ws.path; + } else if (this.isH2) { + return this.stream.http.path[0]; + } + return null; + } + + get quicSecurity() { + return this.stream.quic.security; + } + + get quicKey() { + return this.stream.quic.key; + } + + get quicType() { + return this.stream.quic.type; + } + + get kcpType() { + return this.stream.kcp.type; + } + + get kcpSeed() { + return this.stream.kcp.seed; + } + + get serviceName() { + return this.stream.grpc.serviceName; + } + + isExpiry(index) { + switch (this.protocol) { + case Protocols.VMESS: + if(this.settings.vmesses[index]._expiryTime != null) + return this.settings.vmesses[index]._expiryTime < new Date().getTime(); + return false + case Protocols.VLESS: + if(this.settings.vlesses[index]._expiryTime != null) + return this.settings.vlesses[index]._expiryTime < new Date().getTime(); + return false + case Protocols.TROJAN: + if(this.settings.trojans[index]._expiryTime != null) + return this.settings.trojans[index]._expiryTime < new Date().getTime(); + return false + default: + return false; + } + } + + canEnableTls() { + switch (this.protocol) { + case Protocols.VMESS: + case Protocols.VLESS: + case Protocols.TROJAN: + case Protocols.SHADOWSOCKS: + break; + default: + return false; + } + + switch (this.network) { + case "tcp": + case "ws": + case "http": + case "quic": + case "grpc": + return true; + default: + return false; + } + } + + //this is used for xtls-rprx-vison + canEnableTlsFlow() { + if ((this.stream.security === 'tls') && (this.network === "tcp")) { + switch (this.protocol) { + case Protocols.VLESS: + return true; + default: + return false; + } + } + return false; + } + + canSetTls() { + return this.canEnableTls(); + } + + canEnableXTls() { + switch (this.protocol) { + case Protocols.VLESS: + case Protocols.TROJAN: + break; + default: + return false; + } + return this.network === "tcp"; + } + + canEnableStream() { + switch (this.protocol) { + case Protocols.VMESS: + case Protocols.VLESS: + case Protocols.TROJAN: + case Protocols.SHADOWSOCKS: + return true; + default: + return false; + } + } + + canSniffing() { + switch (this.protocol) { + case Protocols.VMESS: + case Protocols.VLESS: + case Protocols.TROJAN: + case Protocols.SHADOWSOCKS: + return true; + default: + return false; + } + } + + reset() { + this.port = RandomUtil.randomIntRange(10000, 60000); + this.listen = ''; + this.protocol = Protocols.VMESS; + this.settings = Inbound.Settings.getSettings(Protocols.VMESS); + this.stream = new StreamSettings(); + this.tag = ''; + this.sniffing = new Sniffing(); + } + + genVmessLink(address='', remark='', clientIndex=0) { + if (this.protocol !== Protocols.VMESS) { + return ''; + } + let network = this.stream.network; + let type = 'none'; + let host = ''; + let path = ''; + if (network === 'tcp') { + let tcp = this.stream.tcp; + type = tcp.type; + if (type === 'http') { + let request = tcp.request; + path = request.path.join(','); + let index = request.headers.findIndex(header => header.name.toLowerCase() === 'host'); + if (index >= 0) { + host = request.headers[index].value; contacts: admin@thfree.ru |
