fit xray settings #1300

This commit is contained in:
Alireza Ahmadi 2023-12-08 19:45:19 +01:00
parent e5fc20b8ae
commit 38013e5ea9
3 changed files with 679 additions and 340 deletions

View file

@ -3,296 +3,534 @@
<a-tabs :active-key="outModal.activeKey" style="padding: 0; background-color: transparent;" @change="(activeKey) => {outModal.toggleJson(activeKey == '2'); }"> <a-tabs :active-key="outModal.activeKey" style="padding: 0; background-color: transparent;" @change="(activeKey) => {outModal.toggleJson(activeKey == '2'); }">
<a-tab-pane key="1" tab="Form"> <a-tab-pane key="1" tab="Form">
<a-form layout="inline"> <a-form layout="inline">
<a-form-item label='{{ i18n "protocol" }}'> <table width="100%" class="ant-table-tbody">
<a-select v-model="outbound.protocol" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme"> <tr>
<a-select-option v-for="x,y in Protocols" :value="x">[[ y ]]</a-select-option> <td>{{ i18n "protocol" }}</td>
</a-select> <td>
</a-form-item> <a-form-item>
<a-form-item label='{{ i18n "pages.xray.outbound.tag" }}' has-feedback :validate-status="outModal.duplicateTag? 'warning' : 'success'"> <a-select v-model="outbound.protocol" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
<a-input v-model.trim="outbound.tag" style="width: 250px" @change="outModal.check()" placeholder='{{ i18n "pages.xray.outbound.tagDesc" }}'></a-input> <a-select-option v-for="x,y in Protocols" :value="x">[[ y ]]</a-select-option>
</a-form-item> </a-select>
</a-form-item>
</td>
</tr>
<tr>
<td>{{ i18n "pages.xray.outbound.tag" }}</td>
<td>
<a-form-item has-feedback :validate-status="outModal.duplicateTag? 'warning' : 'success'">
<a-input v-model.trim="outbound.tag" style="width: 250px" @change="outModal.check()" placeholder='{{ i18n "pages.xray.outbound.tagDesc" }}'></a-input>
</a-form-item>
</td>
</tr>
<!-- freedom settings--> <!-- freedom settings-->
<template v-if="outbound.protocol === Protocols.Freedom"> <template v-if="outbound.protocol === Protocols.Freedom">
<a-form-item label="Strategy"> <tr>
<a-select <td>Strategy</td>
v-model="outbound.settings.domainStrategy" <td>
style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme"> <a-form-item>
<a-select-option v-for="s in outboundDomainStrategies" :value="s">[[ s ]]</a-select-option> <a-select
</a-select> v-model="outbound.settings.domainStrategy"
</a-form-item> style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
<a-form-item label="Fragment"> <a-select-option v-for="s in outboundDomainStrategies" :value="s">[[ s ]]</a-select-option>
<a-switch </a-select>
:checked="Object.keys(outbound.settings.fragment).length >0" </a-form-item>
@change="checked => outbound.settings.fragment = checked ? new Outbound.FreedomSettings.Fragment() : {}"> </td>
</a-switch> </tr>
</a-form-item> <tr>
<td>Fragment</td>
<td>
<a-form-item>
<a-switch
:checked="Object.keys(outbound.settings.fragment).length >0"
@change="checked => outbound.settings.fragment = checked ? new Outbound.FreedomSettings.Fragment() : {}">
</a-switch>
</a-form-item>
</td>
</tr>
<template v-if="Object.keys(outbound.settings.fragment).length >0"> <template v-if="Object.keys(outbound.settings.fragment).length >0">
<a-form-item label="Packets"> <tr>
<a-select <td>Packets</td>
v-model="outbound.settings.fragment.packets" <td>
style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme"> <a-form-item>
<a-select-option v-for="s in ['1-3','tlshello']" :value="s">[[ s ]]</a-select-option> <a-select
</a-select> v-model="outbound.settings.fragment.packets"
</a-form-item> style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
<a-form-item label="Length"> <a-select-option v-for="s in ['1-3','tlshello']" :value="s">[[ s ]]</a-select-option>
<a-input v-model.trim="outbound.settings.fragment.length" style="width: 250px"></a-input> </a-select>
</a-form-item> </a-form-item>
<a-form-item label="Interval"> </td>
<a-input v-model.trim="outbound.settings.fragment.interval" style="width: 250px"></a-input> </tr>
</a-form-item> <tr>
<td>Length</td>
<td>
<a-form-item>
<a-input v-model.trim="outbound.settings.fragment.length" style="width: 250px"></a-input>
</a-form-item>
</td>
</tr>
<tr>
<td>Interval</td>
<td>
<a-form-item>
<a-input v-model.trim="outbound.settings.fragment.interval" style="width: 250px"></a-input>
</a-form-item>
</td>
</tr>
</template> </template>
</template> </template>
<!-- blackhole settings --> <!-- blackhole settings -->
<template v-if="outbound.protocol === Protocols.Blackhole"> <template v-if="outbound.protocol === Protocols.Blackhole">
<a-form-item label="Response Type"> <tr>
<a-select <td>Response Type</td>
v-model="outbound.settings.type" <td>
style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme"> <a-form-item>
<a-select-option v-for="s in ['', 'none','http']" :value="s">[[ s ]]</a-select-option> <a-select
</a-select> v-model="outbound.settings.type"
</a-form-item> style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option v-for="s in ['', 'none','http']" :value="s">[[ s ]]</a-select-option>
</a-select>
</a-form-item>
</td>
</tr>
</template> </template>
<!-- dns settings --> <!-- dns settings -->
<template v-if="outbound.protocol === Protocols.DNS"> <template v-if="outbound.protocol === Protocols.DNS">
<a-form-item label='{{ i18n "pages.inbounds.network" }}'> <tr>
<a-select <td>{{ i18n "pages.inbounds.network" }}</td>
v-model="outbound.settings.network" <td>
style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme"> <a-form-item>
<a-select-option v-for="s in ['udp','tcp']" :value="s">[[ s ]]</a-select-option> <a-select
</a-select> v-model="outbound.settings.network"
</a-form-item> style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option v-for="s in ['udp','tcp']" :value="s">[[ s ]]</a-select-option>
</a-select>
</a-form-item>
</td>
</tr>
</template> </template>
<!-- Address + Port --> <!-- Address + Port -->
<template v-if="outbound.hasAddressPort()"> <template v-if="outbound.hasAddressPort()">
<a-form-item label='{{ i18n "pages.inbounds.address" }}'> <tr>
<a-input v-model.trim="outbound.settings.address" style="width: 250px"></a-input> <td>{{ i18n "pages.inbounds.address" }}</td>
</a-form-item> <td>
<a-form-item label='{{ i18n "pages.inbounds.port" }}'> <a-form-item>
<a-input-number v-model.number="outbound.settings.port" :min="1" :max="65532"></a-input-number> <a-input v-model.trim="outbound.settings.address" style="width: 250px"></a-input>
</a-form-item> </a-form-item>
</td>
</tr>
<tr>
<td>{{ i18n "pages.inbounds.port" }}</td>
<td>
<a-form-item>
<a-input-number v-model.number="outbound.settings.port" :min="1" :max="65532"></a-input-number>
</a-form-item>
</td>
</tr>
</template> </template>
<!-- Vnext (vless/vmess) settings --> <!-- Vnext (vless/vmess) settings -->
<template v-if="[Protocols.VMess, Protocols.VLESS].includes(outbound.protocol)"> <template v-if="[Protocols.VMess, Protocols.VLESS].includes(outbound.protocol)">
<a-form-item label="ID"> <tr>
<a-input v-model.trim="outbound.settings.id" style="width: 250px"></a-input> <td>ID</td>
</a-form-item> <td>
<a-form-item>
<a-input v-model.trim="outbound.settings.id" style="width: 250px"></a-input>
</a-form-item>
</td>
</tr>
<!-- vless settings --> <!-- vless settings -->
<template v-if="outbound.canEnableTlsFlow()"> <template v-if="outbound.canEnableTlsFlow()">
<a-form-item label="Flow"> <tr>
<a-select v-model="outbound.settings.flow" style="width: 250px" :dropdown-class-name="themeSwitcher.currentTheme"> <td>Flow</td>
<a-select-option value="" selected>{{ i18n "none" }}</a-select-option> <td>
<a-select-option v-for="key in TLS_FLOW_CONTROL" :value="key">[[ key ]]</a-select-option> <a-form-item>
</a-select> <a-select v-model="outbound.settings.flow" style="width: 250px" :dropdown-class-name="themeSwitcher.currentTheme">
</a-form-item> <a-select-option value="" selected>{{ i18n "none" }}</a-select-option>
<a-select-option v-for="key in TLS_FLOW_CONTROL" :value="key">[[ key ]]</a-select-option>
</a-select>
</a-form-item>
</td>
</tr>
</template> </template>
</template> </template>
<!-- Servers (trojan/shadowsocks/socks/http) settings --> <!-- Servers (trojan/shadowsocks/socks/http) settings -->
<template v-if="outbound.hasServers()"> <template v-if="outbound.hasServers()">
<template v-if="outbound.hasUsername()"> <tr v-if="outbound.hasUsername()">
<a-form-item label='{{ i18n "username" }}'> <td>{{ i18n "username" }}</td>
<a-input v-model.trim="outbound.settings.user" style="width: 250px"></a-input> <td>
</a-form-item> <a-form-item>
<a-form-item label='{{ i18n "password" }}'> <a-input v-model.trim="outbound.settings.user" style="width: 250px"></a-input>
<a-input v-model.trim="outbound.settings.password" style="width: 250px"></a-input> </a-form-item>
</a-form-item> </td>
</template> </tr>
<tr>
<td>{{ i18n "password" }}</td>
<td>
<a-form-item>
<a-input v-model.trim="outbound.settings.password" style="width: 250px"></a-input>
</a-form-item>
</td>
</tr>
<!-- shadowsocks --> <!-- shadowsocks -->
<template v-if="outbound.protocol === Protocols.Shadowsocks"> <template v-if="outbound.protocol === Protocols.Shadowsocks">
<a-form-item label='{{ i18n "encryption" }}'> <tr>
<a-select v-model="outbound.settings.method" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme"> <td>{{ i18n "encryption" }}</td>
<a-select-option v-for="method in SSMethods" :value="method">[[ method ]]</a-select-option> <td>
</a-select> <a-form-item>
</a-form-item> <a-select v-model="outbound.settings.method" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
<a-form-item label="UDP over TCP"> <a-select-option v-for="method in SSMethods" :value="method">[[ method ]]</a-select-option>
<a-switch v-model="outbound.settings.uot"></a-switch> </a-select>
</a-form-item> </a-form-item>
</td>
</tr>
<tr>
<td>UDP over TCP</td>
<td>
<a-form-item>
<a-switch v-model="outbound.settings.uot"></a-switch>
</a-form-item>
</td>
</tr>
</template> </template>
</template> </template>
<!-- stream settings --> <!-- stream settings -->
<template v-if="outbound.canEnableStream()"> <template v-if="outbound.canEnableStream()">
<a-form-item label='{{ i18n "transmission" }}'> <tr>
<a-select v-model="outbound.stream.network" @change="streamNetworkChange" <td>{{ i18n "transmission" }}</td>
style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme"> <td>
<a-select-option value="tcp">TCP</a-select-option> <a-form-item>
<a-select-option value="kcp">KCP</a-select-option> <a-select v-model="outbound.stream.network" @change="streamNetworkChange"
<a-select-option value="ws">WebSocket</a-select-option> style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option value="http">HTTP2</a-select-option> <a-select-option value="tcp">TCP</a-select-option>
<a-select-option value="quic">QUIC</a-select-option> <a-select-option value="kcp">KCP</a-select-option>
<a-select-option value="grpc">gRPC</a-select-option> <a-select-option value="ws">WebSocket</a-select-option>
</a-select> <a-select-option value="http">HTTP2</a-select-option>
</a-form-item> <a-select-option value="quic">QUIC</a-select-option>
<a-select-option value="grpc">gRPC</a-select-option>
</a-select>
</a-form-item>
</td>
</tr>
<template v-if="outbound.stream.network === 'tcp'"> <template v-if="outbound.stream.network === 'tcp'">
<a-form-item label='http {{ i18n "camouflage" }}'> <tr>
<a-switch <td>http {{ i18n "camouflage" }}</td>
:checked="outbound.stream.tcp.type === 'http'" <td>
@change="checked => outbound.stream.tcp.type = checked ? 'http' : 'none'"> <a-form-item>
</a-switch> <a-switch
</a-form-item> :checked="outbound.stream.tcp.type === 'http'"
@change="checked => outbound.stream.tcp.type = checked ? 'http' : 'none'">
</a-switch>
</a-form-item>
</td>
</tr>
<template v-if="outbound.stream.tcp.type == 'http'"> <template v-if="outbound.stream.tcp.type == 'http'">
<a-form-item label='{{ i18n "host" }}'> <tr>
<a-input style="width: 250px;" v-model.trim="outbound.stream.tcp.host"></a-input> <td>{{ i18n "host" }}</td>
</a-form-item> <td>
<a-form-item label='{{ i18n "path" }}'> <a-form-item>
<a-input style="width: 250px;" v-model.trim="outbound.stream.tcp.path"></a-input> <a-input style="width: 250px;" v-model.trim="outbound.stream.tcp.host"></a-input>
</a-form-item> </a-form-item>
</td>
</tr>
<tr>
<td>{{ i18n "path" }}</td>
<td>
<a-form-item>
<a-input style="width: 250px;" v-model.trim="outbound.stream.tcp.path"></a-input>
</a-form-item>
</td>
</tr>
</template> </template>
</template> </template>
<!-- kcp --> <!-- kcp -->
<template v-if="outbound.stream.network === 'kcp'"> <template v-if="outbound.stream.network === 'kcp'">
<a-form-item label='{{ i18n "camouflage" }}'> <tr>
<a-select v-model="outbound.stream.kcp.type" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme"> <td>{{ i18n "camouflage" }}</td>
<a-select-option value="none">none (not camouflage)</a-select-option> <td>
<a-select-option value="srtp">srtp (video call)</a-select-option> <a-form-item>
<a-select-option value="utp">utp (BT download)</a-select-option> <a-select v-model="outbound.stream.kcp.type" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option value="wechat-video">wechat-video (WeChat video)</a-select-option> <a-select-option value="none">none (not camouflage)</a-select-option>
<a-select-option value="dtls">dtls (DTLS 1.2 packages)</a-select-option> <a-select-option value="srtp">srtp (video call)</a-select-option>
<a-select-option value="wireguard">wireguard (wireguard packages)</a-select-option> <a-select-option value="utp">utp (BT download)</a-select-option>
</a-select> <a-select-option value="wechat-video">wechat-video (WeChat video)</a-select-option>
</a-form-item> <a-select-option value="dtls">dtls (DTLS 1.2 packages)</a-select-option>
<a-form-item label='{{ i18n "password" }}'> <a-select-option value="wireguard">wireguard (wireguard packages)</a-select-option>
<a-input v-model="outbound.stream.kcp.seed" style="width: 250px;"></a-input> </a-select>
</a-form-item> </a-form-item>
<a-form-item label="mtu"> </td>
<a-input-number v-model.number="outbound.stream.kcp.mtu"></a-input-number> </tr>
</a-form-item> <tr>
<a-form-item label="tti (ms)"> <td>{{ i18n "password" }}</td>
<a-input-number v-model.number="outbound.stream.kcp.tti"></a-input-number> <td>
</a-form-item> <a-form-item>
<a-form-item label="uplink capacity (MB/S)"> <a-input v-model="outbound.stream.kcp.seed" style="width: 250px;"></a-input>
<a-input-number v-model.number="outbound.stream.kcp.upCap"></a-input-number> </a-form-item>
</a-form-item> </td>
<a-form-item label="downlink capacity (MB/S)"> </tr>
<a-input-number v-model.number="outbound.stream.kcp.downCap"></a-input-number> <tr>
</a-form-item> <td>mtu</td>
<a-form-item label="congestion"> <td>
<a-switch v-model="outbound.stream.kcp.congestion"></a-switch> <a-form-item>
</a-form-item> <a-input-number v-model.number="outbound.stream.kcp.mtu"></a-input-number>
<a-form-item label="read buffer size (MB)"> </a-form-item>
<a-input-number v-model.number="outbound.stream.kcp.readBuffer"></a-input-number> </td>
</a-form-item> </tr>
<a-form-item label="write buffer size (MB)"> <tr>
<a-input-number v-model.number="outbound.stream.kcp.writeBuffer"></a-input-number> <td>tti (ms)</td>
</a-form-item> <td>
<a-form-item>
<a-input-number v-model.number="outbound.stream.kcp.tti"></a-input-number>
</a-form-item>
</td>
</tr>
<tr>
<td>uplink capacity (MB/S)</td>
<td>
<a-form-item>
<a-input-number v-model.number="outbound.stream.kcp.upCap"></a-input-number>
</a-form-item>
</td>
</tr>
<tr>
<td>downlink capacity (MB/S)</td>
<td>
<a-form-item>
<a-input-number v-model.number="outbound.stream.kcp.downCap"></a-input-number>
</a-form-item>
</td>
</tr>
<tr>
<td>congestion</td>
<td>
<a-form-item>
<a-switch v-model="outbound.stream.kcp.congestion"></a-switch>
</a-form-item>
</td>
</tr>
<tr>
<td>read buffer size (MB)</td>
<td>
<a-form-item>
<a-input-number v-model.number="outbound.stream.kcp.readBuffer"></a-input-number>
</a-form-item>
</td>
</tr>
<tr>
<td>write buffer size (MB)</td>
<td>
<a-form-item>
<a-input-number v-model.number="outbound.stream.kcp.writeBuffer"></a-input-number>
</a-form-item>
</td>
</tr>
</template> </template>
<!-- ws --> <!-- ws -->
<template v-if="outbound.stream.network === 'ws'"> <template v-if="outbound.stream.network === 'ws'">
<a-form-item label='{{ i18n "host" }}'> <tr>
<a-input style="width: 250px" v-model="outbound.stream.ws.host"></a-input> <td>{{ i18n "host" }}</td>
</a-form-item> <td><a-form-item><a-input style="width: 250px" v-model="outbound.stream.ws.host"></a-input></a-form-item></td>
<a-form-item label='{{ i18n "path" }}'> </tr>
<a-input style="width: 250px;" v-model.trim="outbound.stream.ws.path"></a-input> <tr>
</a-form-item> <td>{{ i18n "path" }}</td>
<td><a-form-item><a-input style="width: 250px;" v-model.trim="outbound.stream.ws.path"></a-input></a-form-item></td>
</tr>
</template> </template>
<!-- http --> <!-- http -->
<template v-if="outbound.stream.network === 'http'"> <template v-if="outbound.stream.network === 'http'">
<a-form-item label='{{ i18n "host" }}'> <tr>
<a-input v-model.trim="outbound.stream.http.host" style="width: 250px;"></a-input> <td>{{ i18n "host" }}</td>
</a-form-item> <td>
<a-form-item label='{{ i18n "path" }}'> <a-form-item>
<a-input v-model.trim="outbound.stream.http.path" style="width: 250px;"></a-input> <a-input v-model.trim="outbound.stream.http.host" style="width: 250px;"></a-input>
</a-form-item> </a-form-item>
</td>
</tr>
<tr>
<td>{{ i18n "path" }}</td>
<td>
<a-form-item>
<a-input v-model.trim="outbound.stream.http.path" style="width: 250px;"></a-input>
</a-form-item>
</td>
</tr>
</template> </template>
<!-- quic --> <!-- quic -->
<template v-if="outbound.stream.network === 'quic'"> <template v-if="outbound.stream.network === 'quic'">
<a-form-item label='{{ i18n "pages.inbounds.stream.quic.encryption" }}'> <tr>
<a-select v-model="outbound.stream.quic.security" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme"> <td>{{ i18n "pages.inbounds.stream.quic.encryption" }}</td>
<a-select-option value="none">none</a-select-option> <td>
<a-select-option value="aes-128-gcm">aes-128-gcm</a-select-option> <a-form-item>
<a-select-option value="chacha20-poly1305">chacha20-poly1305</a-select-option> <a-select v-model="outbound.stream.quic.security" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
</a-select> <a-select-option value="none">none</a-select-option>
</a-form-item> <a-select-option value="aes-128-gcm">aes-128-gcm</a-select-option>
<a-form-item label='{{ i18n "password" }}'> <a-select-option value="chacha20-poly1305">chacha20-poly1305</a-select-option>
<a-input v-model.trim="outbound.stream.quic.key" style="width: 250px;"></a-input> </a-select>
</a-form-item> </a-form-item>
<a-form-item label='{{ i18n "camouflage" }}'> </td>
<a-select v-model="outbound.stream.quic.type" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme"> </tr>
<a-select-option value="none">none (not camouflage)</a-select-option> <tr>
<a-select-option value="srtp">srtp (video call)</a-select-option> <td>{{ i18n "password" }}</td>
<a-select-option value="utp">utp (BT download)</a-select-option> <td>
<a-select-option value="wechat-video">wechat-video (WeChat video)</a-select-option> <a-form-item>
<a-select-option value="dtls">dtls (DTLS 1.2 packages)</a-select-option> <a-input v-model.trim="outbound.stream.quic.key" style="width: 250px;"></a-input>
<a-select-option value="wireguard">wireguard (wireguard packages)</a-select-option> </a-form-item>
</a-select> </td>
</a-form-item> </tr>
<tr>
<td>{{ i18n "camouflage" }}</td>
<td>
<a-form-item>
<a-select v-model="outbound.stream.quic.type" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option value="none">none (not camouflage)</a-select-option>
<a-select-option value="srtp">srtp (video call)</a-select-option>
<a-select-option value="utp">utp (BT download)</a-select-option>
<a-select-option value="wechat-video">wechat-video (WeChat video)</a-select-option>
<a-select-option value="dtls">dtls (DTLS 1.2 packages)</a-select-option>
<a-select-option value="wireguard">wireguard (wireguard packages)</a-select-option>
</a-select>
</a-form-item>
</td>
</tr>
</template> </template>
<!-- grpc --> <!-- grpc -->
<template v-if="outbound.stream.network === 'grpc'"> <template v-if="outbound.stream.network === 'grpc'">
<a-form-item label="serviceName"> <tr>
<a-input v-model.trim="outbound.stream.grpc.serviceName" style="width: 250px;"></a-input> <td>serviceName</td>
</a-form-item> <td>
<a-form-item label="MultiMode"> <a-form-item>
<a-switch v-model="outbound.stream.grpc.multiMode"></a-switch> <a-input v-model.trim="outbound.stream.grpc.serviceName" style="width: 250px;"></a-input>
</a-form-item> </a-form-item>
</td>
</tr>
<tr>
<td>MultiMode</td>
<td>
<a-form-item>
<a-switch v-model="outbound.stream.grpc.multiMode"></a-switch>
</a-form-item>
</td>
</tr>
</template> </template>
</template> </template>
<!-- tls settings --> <!-- tls settings -->
<template v-if="outbound.canEnableTls()"> <template v-if="outbound.canEnableTls()">
<a-form-item label='{{ i18n "security" }}'> <tr>
<a-radio-group v-model="outbound.stream.security" button-style="solid"> <td>{{ i18n "security" }}</td>
<a-radio-button value="none">{{ i18n "none" }}</a-radio-button> <td>
<a-radio-button value="tls">TLS</a-radio-button> <a-form-item>
<a-radio-button v-if="outbound.canEnableReality()" value="reality">Reality</a-radio-button> <a-radio-group v-model="outbound.stream.security" button-style="solid">
</a-radio-group> <a-radio-button value="none">{{ i18n "none" }}</a-radio-button>
</a-form-item><br /> <a-radio-button value="tls">TLS</a-radio-button>
<template v-if="outbound.stream.isTls"> <a-radio-button v-if="outbound.canEnableReality()" value="reality">Reality</a-radio-button>
<a-form-item label="SNI" placeholder="Server Name Indication"> </a-radio-group>
<a-input v-model.trim="outbound.stream.tls.serverName" style="width: 250px"></a-input> </a-form-item>
</a-form-item> </td>
<a-form-item label="uTLS"> </tr>
<a-select v-model="outbound.stream.tls.fingerprint" <template v-if="outbound.stream.isTls">
style="width: 250px" :dropdown-class-name="themeSwitcher.currentTheme"> <tr>
<a-select-option value=''>None</a-select-option> <td>SNI</td>
<a-select-option v-for="key in UTLS_FINGERPRINT" :value="key">[[ key ]]</a-select-option> <td>
</a-select> <a-form-item placeholder="Server Name Indication">
</a-form-item> <a-input v-model.trim="outbound.stream.tls.serverName" style="width: 250px"></a-input>
<a-form-item label="ALPN"> </a-form-item>
<a-select </td>
mode="multiple" </tr>
style="width: 250px" <tr>
:dropdown-class-name="themeSwitcher.currentTheme" <td>uTLS</td>
v-model="outbound.stream.tls.alpn"> <td>
<a-select-option v-for="alpn in ALPN_OPTION" :value="alpn">[[ alpn ]]</a-select-option> <a-form-item>
</a-select> <a-select v-model="outbound.stream.tls.fingerprint"
</a-form-item> style="width: 250px" :dropdown-class-name="themeSwitcher.currentTheme">
<a-form-item label="Allow insecure"> <a-select-option value=''>None</a-select-option>
<a-switch v-model="outbound.stream.tls.allowInsecure"></a-switch> <a-select-option v-for="key in UTLS_FINGERPRINT" :value="key">[[ key ]]</a-select-option>
</a-form-item> </a-select>
</template> </a-form-item>
</td>
</tr>
<tr>
<td>ALPN</td>
<td>
<a-form-item>
<a-select
mode="multiple"
style="width: 250px"
:dropdown-class-name="themeSwitcher.currentTheme"
v-model="outbound.stream.tls.alpn">
<a-select-option v-for="alpn in ALPN_OPTION" :value="alpn">[[ alpn ]]</a-select-option>
</a-select>
</a-form-item>
</td>
</tr>
<tr>
<td>Allow insecure</td>
<td>
<a-form-item>
<a-switch v-model="outbound.stream.tls.allowInsecure"></a-switch>
</a-form-item>
</td>
</tr>
</template>
<!-- reality settings --> <!-- reality settings -->
<template v-if="outbound.stream.isReality"> <template v-if="outbound.stream.isReality">
<a-form-item label='{{ i18n "domainName" }}'> <tr>
<a-input v-model.trim="outbound.stream.reality.serverName" style="width: 250px"></a-input> <td>{{ i18n "domainName" }}</td>
</a-form-item> <td>
<a-form-item label="uTLS"> <a-form-item>
<a-select v-model="outbound.stream.reality.fingerprint" <a-input v-model.trim="outbound.stream.reality.serverName" style="width: 250px"></a-input>
style="width: 250px" :dropdown-class-name="themeSwitcher.currentTheme"> </a-form-item>
<a-select-option v-for="key in UTLS_FINGERPRINT" :value="key">[[ key ]]</a-select-option> </td>
</a-select> </tr>
</a-form-item> <tr>
<a-form-item label="Short Id"> <td>uTLS</td>
<a-input v-model.trim="outbound.stream.reality.shortId" style="width:250px"></a-input> <td>
</a-form-item> <a-form-item>
<a-form-item label="SpiderX"> <a-select v-model="outbound.stream.reality.fingerprint"
<a-input v-model.trim="outbound.stream.reality.spiderX" style="width:250px"></a-input> style="width: 250px" :dropdown-class-name="themeSwitcher.currentTheme">
</a-form-item> <a-select-option v-for="key in UTLS_FINGERPRINT" :value="key">[[ key ]]</a-select-option>
<a-form-item label="Public Key"> </a-select>
<a-input v-model.trim="outbound.stream.reality.publicKey" style="width: 250px"></a-input> </a-form-item>
</a-form-item> </td>
</template> </tr>
<tr>
<td>Short Id</td>
<td>
<a-form-item>
<a-input v-model.trim="outbound.stream.reality.shortId" style="width:250px"></a-input>
</a-form-item>
</td>
</tr>
<tr>
<td>SpiderX</td>
<td>
<a-form-item>
<a-input v-model.trim="outbound.stream.reality.spiderX" style="width:250px"></a-input>
</a-form-item>
</td>
</tr>
<tr>
<td>Public Key</td>
<td>
<a-form-item>
<a-input v-model.trim="outbound.stream.reality.publicKey" style="width: 250px"></a-input>
</a-form-item>
</td>
</tr>
</template>
</template> </template>
</table>
</a-form> </a-form>
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="2" tab="JSON" force-render="true"> <a-tab-pane key="2" tab="JSON" force-render="true">

View file

@ -3,41 +3,78 @@
:confirm-loading="reverseModal.confirmLoading" :closable="true" :mask-closable="false" :confirm-loading="reverseModal.confirmLoading" :closable="true" :mask-closable="false"
:ok-text="reverseModal.okText" cancel-text='{{ i18n "close" }}' :class="themeSwitcher.currentTheme"> :ok-text="reverseModal.okText" cancel-text='{{ i18n "close" }}' :class="themeSwitcher.currentTheme">
<a-form layout="inline"> <a-form layout="inline">
<a-form-item label='{{ i18n "pages.xray.outbound.type" }}'> <table width="100%" class="ant-table-tbody">
<a-select v-model="reverseModal.reverse.type" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme"> <tr>
<a-select-option v-for="x,y in reverseTypes" :value="y">[[ x ]]</a-select-option> <td>{{ i18n "pages.xray.outbound.type" }}</td>
</a-select> <td>
</a-form-item> <a-form-item>
<a-form-item label='{{ i18n "pages.xray.outbound.tag" }}'> <a-select v-model="reverseModal.reverse.type" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
<a-input v-model.trim="reverseModal.reverse.tag" style="width: 250px"></a-input> <a-select-option v-for="x,y in reverseTypes" :value="y">[[ x ]]</a-select-option>
</a-form-item> </a-select>
<a-form-item label='{{ i18n "pages.xray.outbound.domain" }}'> </a-form-item>
<a-input v-model.trim="reverseModal.reverse.domain" style="width: 250px"></a-input> </td>
</a-form-item> </tr>
<tr>
<td>{{ i18n "pages.xray.outbound.tag" }}</td>
<td>
<a-form-item>
<a-input v-model.trim="reverseModal.reverse.tag" style="width: 250px"></a-input>
</a-form-item>
</td>
</tr>
<tr>
<td>{{ i18n "pages.xray.outbound.domain" }}</td>
<td>
<a-form-item>
<a-input v-model.trim="reverseModal.reverse.domain" style="width: 250px"></a-input>
</a-form-item>
</td>
</tr>
<template v-if="reverseModal.reverse.type=='bridge'"> <template v-if="reverseModal.reverse.type=='bridge'">
<a-form-item label='{{ i18n "pages.xray.outbound.intercon" }}'> <tr>
<a-select v-model="reverseModal.rules[0].outboundTag" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme"> <td>{{ i18n "pages.xray.outbound.intercon" }}</td>
<a-select-option v-for="x in reverseModal.outboundTags" :value="x">[[ x ]]</a-select-option> <td>
</a-select> <a-form-item>
</a-form-item> <a-select v-model="reverseModal.rules[0].outboundTag" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
<a-form-item label='{{ i18n "pages.xray.rules.outbound" }}'> <a-select-option v-for="x in reverseModal.outboundTags" :value="x">[[ x ]]</a-select-option>
<a-select v-model="reverseModal.rules[1].outboundTag" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme"> </a-select>
<a-select-option v-for="x in reverseModal.outboundTags" :value="x">[[ x ]]</a-select-option> </a-form-item>
</a-select> </td>
</a-form-item> </tr>
<tr>
<td>{{ i18n "pages.xray.rules.outbound" }}</td>
<td>
<a-form-item>
<a-select v-model="reverseModal.rules[1].outboundTag" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option v-for="x in reverseModal.outboundTags" :value="x">[[ x ]]</a-select-option>
</a-select>
</a-form-item>
</td>
</tr>
</template> </template>
<template v-else> <template v-else>
<a-form-item label='{{ i18n "pages.xray.outbound.intercon" }}'> <tr>
<a-checkbox-group <td>{{ i18n "pages.xray.outbound.intercon" }}</td>
v-model="reverseModal.rules[0].inboundTag" <td>
:options="reverseModal.inboundTags"></a-checkbox-group> <a-form-item>
</a-form-item> <a-checkbox-group
<a-form-item label='{{ i18n "pages.xray.rules.inbound" }}'> v-model="reverseModal.rules[0].inboundTag"
<a-checkbox-group :options="reverseModal.inboundTags"></a-checkbox-group>
v-model="reverseModal.rules[1].inboundTag" </a-form-item>
:options="reverseModal.inboundTags"></a-checkbox-group> </td>
</a-form-item> </tr>
<tr>
<td>{{ i18n "pages.xray.rules.inbound" }}</td>
<td>
<a-form-item>
<a-checkbox-group
v-model="reverseModal.rules[1].inboundTag"
:options="reverseModal.inboundTags"></a-checkbox-group>
</a-form-item>
</td>
</tr>
</template> </template>
</table>
</a-form> </a-form>
</a-modal> </a-modal>
<script> <script>

View file

@ -3,87 +3,149 @@
:confirm-loading="ruleModal.confirmLoading" :closable="true" :mask-closable="false" :confirm-loading="ruleModal.confirmLoading" :closable="true" :mask-closable="false"
:ok-text="ruleModal.okText" cancel-text='{{ i18n "close" }}' :class="themeSwitcher.currentTheme"> :ok-text="ruleModal.okText" cancel-text='{{ i18n "close" }}' :class="themeSwitcher.currentTheme">
<a-form layout="inline"> <a-form layout="inline">
<a-form-item label='Domain Matcher'> <table width="100%" class="ant-table-tbody">
<a-select v-model="ruleModal.rule.domainMatcher" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme"> <tr>
<a-select-option v-for="dm in ['','hybrid','linear']" :value="dm">[[ dm ]]</a-select-option> <td style="width: 30%;">Domain Matcher</td>
</a-select> <td>
</a-form-item> <a-form-item>
<a-form-item label='Source IPs'> <a-select v-model="ruleModal.rule.domainMatcher" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
<a-tooltip> <a-select-option v-for="dm in ['','hybrid','linear']" :value="dm">[[ dm ]]</a-select-option>
<template slot="title"> </a-select>
<span>{{ i18n "pages.xray.rules.useComma" }}</span> </a-form-item>
</template> </td>
<a-icon type="question-circle"></a-icon> </tr>
</a-tooltip> <tr>
<a-input v-model.trim="ruleModal.rule.source" style="width: 250px"></a-input> <td>Source IPs
</a-form-item> <a-tooltip>
<a-form-item label='Source Port'> <template slot="title">
<a-tooltip> <span>{{ i18n "pages.xray.rules.useComma" }}</span>
<template slot="title"> </template>
<span>{{ i18n "pages.xray.rules.useComma" }}</span> <a-icon type="question-circle"></a-icon>
</template> </a-tooltip>
<a-icon type="question-circle"></a-icon> </td>
</a-tooltip> <td>
<a-input v-model.trim="ruleModal.rule.sourcePort" style="width: 250px"></a-input> <a-form-item>
</a-form-item> <a-input v-model.trim="ruleModal.rule.source" style="width: 250px"></a-input>
<a-form-item label='Network'> </a-form-item>
<a-select v-model="ruleModal.rule.network" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme"> </td>
<a-select-option v-for="x in ['','tcp','tdp','tcp,udp']" :value="x">[[ x ]]</a-select-option> </tr>
</a-select> <tr>
</a-form-item> <td>Source Port
<a-form-item label='Protocol'> <a-tooltip>
<a-select v-model="ruleModal.rule.protocol" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme"> <template slot="title">
<a-select-option v-for="x in ['','http','tls','bittorrent']" :value="x">[[ x ]]</a-select-option> <span>{{ i18n "pages.xray.rules.useComma" }}</span>
</a-select> </template>
</a-form-item> <a-icon type="question-circle"></a-icon>
<a-form-item label='Attributes'> </a-tooltip>
<a-button size="small" style="margin-left: 10px" @click="ruleModal.rule.attrs.push(['', ''])">+</a-button> </td>
<a-input-group compact v-for="(attr,index) in ruleModal.rule.attrs"> <td>
<a-input style="width: 50%" v-model="attr[0]" placeholder='{{ i18n "pages.inbounds.stream.general.name" }}'> <a-form-item>
<template slot="addonBefore" style="margin: 0;">[[ index+1 ]]</template> <a-input v-model.trim="ruleModal.rule.sourcePort" style="width: 250px"></a-input>
</a-input> </a-form-item>
<a-input style="width: 50%" v-model="attr[1]" placeholder='{{ i18n "pages.inbounds.stream.general.value" }}'> </td>
<a-button slot="addonAfter" size="small" @click="ruleModal.rule.attrs.splice(index,1)">-</a-button> </tr>
</a-input> <tr>
</a-input-group> <td>Network</td>
</a-form-item> <td>
<a-form-item label='IP'> <a-form-item>
<a-tooltip> <a-select v-model="ruleModal.rule.network" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
<template slot="title"> <a-select-option v-for="x in ['','tcp','tdp','tcp,udp']" :value="x">[[ x ]]</a-select-option>
<span>{{ i18n "pages.xray.rules.useComma" }}</span> </a-select>
</template> </a-form-item>
<a-icon type="question-circle"></a-icon> </td>
</a-tooltip> </tr>
<a-input v-model.trim="ruleModal.rule.ip" style="width: 250px"></a-input> <tr>
</a-form-item> <td>Protocol</td>
<a-form-item label='Domain'> <td>
<a-tooltip> <a-form-item>
<template slot="title"> <a-select v-model="ruleModal.rule.protocol" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
<span>{{ i18n "pages.xray.rules.useComma" }}</span> <a-select-option v-for="x in ['','http','tls','bittorrent']" :value="x">[[ x ]]</a-select-option>
</template> </a-select>
<a-icon type="question-circle"></a-icon> </a-form-item>
</a-tooltip> </td>
<a-input v-model.trim="ruleModal.rule.domain" style="width: 250px"></a-input> </tr>
</a-form-item> <tr>
<a-form-item label='Port'> <td colspan="2">
<a-tooltip> <a-form-item>
<template slot="title"> <span>Attributes</span>
<span>{{ i18n "pages.xray.rules.useComma" }}</span> <a-button size="small" style="margin-left: 10px" @click="ruleModal.rule.attrs.push(['', ''])">+</a-button>
</template> <a-input-group compact v-for="(attr,index) in ruleModal.rule.attrs">
<a-icon type="question-circle"></a-icon> <a-input style="width: 50%" v-model="attr[0]" placeholder='{{ i18n "pages.inbounds.stream.general.name" }}'>
</a-tooltip> <template slot="addonBefore" style="margin: 0;">[[ index+1 ]]</template>
<a-input v-model.trim="ruleModal.rule.port" style="width: 250px"></a-input> </a-input>
</a-form-item> <a-input style="width: 50%" v-model="attr[1]" placeholder='{{ i18n "pages.inbounds.stream.general.value" }}'>
<a-form-item label='Inbound Tags'> <a-button slot="addonAfter" size="small" @click="ruleModal.rule.attrs.splice(index,1)">-</a-button>
<a-select v-model="ruleModal.rule.inboundTag" mode="multiple" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme"> </a-input>
<a-select-option v-for="tag in ruleModal.inboundTags" :value="tag">[[ tag ]]</a-select-option> </a-input-group>
</a-select> </a-form-item>
</a-form-item> </td>
<a-form-item label='Outbound Tag'> </tr>
<a-select v-model="ruleModal.rule.outboundTag" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme"> <tr>
<a-select-option v-for="tag in ruleModal.outboundTags" :value="tag">[[ tag ]]</a-select-option> <td>IP
</a-select> <a-tooltip>
</a-form-item> <template slot="title">
<span>{{ i18n "pages.xray.rules.useComma" }}</span>
</template>
<a-icon type="question-circle"></a-icon>
</a-tooltip>
</td>
<td>
<a-form-item>
<a-input v-model.trim="ruleModal.rule.ip" style="width: 250px"></a-input>
</a-form-item>
</td>
</tr>
<tr>
<td>Domain
<a-tooltip>
<template slot="title">
<span>{{ i18n "pages.xray.rules.useComma" }}</span>
</template>
<a-icon type="question-circle"></a-icon>
</a-tooltip>
</td>
<td>
<a-form-item>
<a-input v-model.trim="ruleModal.rule.domain" style="width: 250px"></a-input>
</a-form-item>
</td>
</tr>
<tr>
<td>Port
<a-tooltip>
<template slot="title">
<span>{{ i18n "pages.xray.rules.useComma" }}</span>
</template>
<a-icon type="question-circle"></a-icon>
</a-tooltip>
</td>
<td>
<a-form-item>
<a-input v-model.trim="ruleModal.rule.port" style="width: 250px"></a-input>
</a-form-item>
</td>
</tr>
<tr>
<td>Inbound Tags</td>
<td>
<a-form-item>
<a-select v-model="ruleModal.rule.inboundTag" mode="multiple" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option v-for="tag in ruleModal.inboundTags" :value="tag">[[ tag ]]</a-select-option>
</a-select>
</a-form-item>
</td>
</tr>
<tr>
<td>Outbound Tag</td>
<td>
<a-form-item>
<a-select v-model="ruleModal.rule.outboundTag" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option v-for="tag in ruleModal.outboundTags" :value="tag">[[ tag ]]</a-select-option>
</a-select>
</a-form-item>
</td>
</tr>
</table>
</a-form> </a-form>
</a-modal> </a-modal>
<script> <script>
@ -96,6 +158,7 @@
isEdit: false, isEdit: false,
confirm: null, confirm: null,
rule: { rule: {
type: "field",
domainMatcher: "", domainMatcher: "",
domain: "", domain: "",
ip: "", ip: "",
@ -173,6 +236,7 @@
value = ruleModal.rule; value = ruleModal.rule;
rule = {}; rule = {};
newRule = {}; newRule = {};
rule.type = "field";
rule.domainMatcher = value.domainMatcher; rule.domainMatcher = value.domainMatcher;
rule.domain = value.domain.length>0 ? value.domain.split(',') : []; rule.domain = value.domain.length>0 ? value.domain.split(',') : [];
rule.ip = value.ip.length>0 ? value.ip.split(',') : []; rule.ip = value.ip.length>0 ? value.ip.split(',') : [];