Files
x-ui/web/html/x-ui/inbound_modal.html
2021-05-27 23:04:39 +08:00

535 lines
24 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{{define "inboundModal"}}
<a-modal id="inbound-modal" v-model="inModal.visible" :title="inModal.title" @ok="inModal.ok"
:confirm-loading="inModal.confirmLoading" :closable="true" :mask-closable="false"
:ok-text="inModal.okText" cancel-text='{{ i18n "close" }}'>
<!-- base -->
<a-form layout="inline">
<a-form-item label='{{ i18n "remark" }}'>
<a-input v-model.trim="inModal.inbound.remark"></a-input>
</a-form-item>
<a-form-item label='{{ i18n "enable" }}'>
<a-switch v-model="inModal.inbound.enable"></a-switch>
</a-form-item>
<a-form-item label='{{ i18n "protocol" }}'>
<a-select v-model="inModal.inbound.protocol" style="width: 160px;"
@change="protocolChange">
<a-select-option v-for="p in Protocols" :key="p" :value="p">[[ p ]]</a-select-option>
</a-select>
</a-form-item>
<a-form-item>
<span slot="label">
监听 IP
<a-tooltip>
<template slot="title">
不懂请保持默认
</template>
<a-icon type="question-circle" theme="filled"></a-icon>
</a-tooltip>
</span>
<a-input v-model.trim="inModal.inbound.listen"></a-input>
</a-form-item>
<a-form-item label="端口">
<a-input type="number" v-model.number="inModal.inbound.port"></a-input>
</a-form-item>
</a-form>
<!-- vmess settings -->
<a-form v-if="inModal.inbound.protocol === Protocols.VMESS"
layout="inline">
<a-form-item label="id">
<a-input v-model.trim="inModal.inbound.settings.vmesses[0].id"></a-input>
</a-form-item>
<a-form-item label="额外 ID">
<a-input type="number" v-model.number="inModal.inbound.settings.vmesses[0].alterId"></a-input>
</a-form-item>
<a-form-item label="禁用不安全加密">
<a-switch v-model.number="inModal.inbound.settings.disableInsecure"></a-switch>
</a-form-item>
</a-form>
<!-- vless settings -->
<a-form v-if="inModal.inbound.protocol === Protocols.VLESS"
layout="inline">
<a-form-item label="id">
<a-input v-model.trim="inModal.inbound.settings.vlesses[0].id"></a-input>
</a-form-item>
<a-form-item label="flow">
<a-select v-model="inModal.inbound.settings.vlesses[0].flow" style="width: 150px">
<a-select-option value=""></a-select-option>
<a-select-option v-for="key in VLESS_FLOW" :value="key">[[ key ]]</a-select-option>
</a-select>
</a-form-item>
</a-form>
<a-form v-if="inModal.inbound.protocol === Protocols.VLESS"
layout="inline">
<a-form-item label="fallbacks">
<a-row>
<a-button type="primary" size="small"
@click="inModal.inbound.settings.addFallback()">
+
</a-button>
</a-row>
</a-form-item>
</a-form>
<!-- vless fallbacks -->
<a-form v-for="(fallback, index) in inModal.inbound.settings.fallbacks" layout="inline">
<a-form-item>
<a-divider>
fallback[[ index + 1 ]]
<a-icon type="delete" @click="() => inModal.inbound.settings.delFallback(index)" style="color: rgb(255, 77, 79);cursor: pointer;"/>
</a-divider>
</a-form-item>
<a-form-item label="name">
<a-input v-model="fallback.name"></a-input>
</a-form-item>
<a-form-item label="alpn">
<a-input v-model="fallback.alpn"></a-input>
</a-form-item>
<a-form-item label="path">
<a-input v-model="fallback.path"></a-input>
</a-form-item>
<a-form-item label="dest">
<a-input v-model="fallback.dest"></a-input>
</a-form-item>
<a-form-item label="xver">
<a-input type="number" v-model.number="fallback.xver"></a-input>
</a-form-item>
</a-form>
<!-- trojan settings -->
<a-form v-if="inModal.inbound.protocol === Protocols.TROJAN"
layout="inline">
<a-form-item label="密码">
<a-input v-model.trim="inModal.inbound.settings.clients[0].password"></a-input>
</a-form-item>
</a-form>
<!-- shadowsocks -->
<a-form v-if="inModal.inbound.protocol === Protocols.SHADOWSOCKS"
layout="inline">
<a-form-item label="加密">
<a-select v-model="inModal.inbound.settings.method" style="width: 165px;">
<a-select-option v-for="method in SSMethods" :value="method">[[ method ]]</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="密码">
<a-input v-model.trim="inModal.inbound.settings.password"></a-input>
</a-form-item>
<a-form-item label="网络">
<a-select v-model="inModal.inbound.settings.network" style="width: 100px;">
<a-select-option value="tcp,udp">tcp+udp</a-select-option>
<a-select-option value="tcp">tcp</a-select-option>
<a-select-option value="udp">udp</a-select-option>
</a-select>
</a-form-item>
</a-form>
<!-- stream settings -->
<template v-if="inModal.inbound.protocol === Protocols.VMESS
|| inModal.inbound.protocol === Protocols.VLESS
|| inModal.inbound.protocol === Protocols.SHADOWSOCKS">
<!-- select stream network -->
<a-form layout="inline">
<a-form-item label="传输">
<a-select v-model="inModal.inbound.stream.network" @change="streamNetworkChange">
<a-select-option value="tcp">tcp</a-select-option>
<a-select-option value="kcp">kcp</a-select-option>
<a-select-option value="ws">ws</a-select-option>
<a-select-option value="http">http</a-select-option>
<a-select-option value="quic">quic</a-select-option>
</a-select>
</a-form-item>
</a-form>
<!-- vmess tcp -->
<template v-if="inModal.inbound.stream.network === 'tcp'">
<!-- vmess tcp type -->
<a-form layout="inline">
<a-form-item label="http 伪装">
<a-switch
:checked="inModal.inbound.stream.tcp.type === 'http'"
@change="checked => inModal.inbound.stream.tcp.type = checked ? 'http' : 'none'">
</a-switch>
</a-form-item>
</a-form>
<!-- vmess tcp request -->
<a-form v-if="inModal.inbound.stream.tcp.type === 'http'"
layout="inline">
<a-form-item label="请求版本">
<a-input v-model.trim="inModal.inbound.stream.tcp.request.version"></a-input>
</a-form-item>
<a-form-item label="请求方法">
<a-input v-model.trim="inModal.inbound.stream.tcp.request.method"></a-input>
</a-form-item>
<a-form-item label="请求路径">
<a-row v-for="(path, index) in inModal.inbound.stream.tcp.request.path">
<a-input v-model.trim="inModal.inbound.stream.tcp.request.path[index]"></a-input>
</a-row>
</a-form-item>
<a-form-item label="请求头">
<a-row>
<a-button size="small"
@click="inModal.inbound.stream.tcp.request.addHeader('Host', 'xxx.com')">
+
</a-button>
</a-row>
<a-input-group v-for="(header, index) in inModal.inbound.stream.tcp.request.headers">
<a-input style="width: 50%" v-model.trim="header.name"
addon-before="名称"></a-input>
<a-input style="width: 50%" v-model.trim="header.value"
addon-before="值">
<template slot="addonAfter">
<a-button size="small"
@click="inModal.inbound.stream.tcp.request.removeHeader(index)">
-
</a-button>
</template>
</a-input>
</a-input-group>
</a-form-item>
</a-form>
<!-- vmess tcp response -->
<a-form v-if="inModal.inbound.stream.tcp.type === 'http'"
layout="inline">
<a-form-item label="响应版本">
<a-input v-model.trim="inModal.inbound.stream.tcp.response.version"></a-input>
</a-form-item>
<a-form-item label="响应状态">
<a-input v-model.trim="inModal.inbound.stream.tcp.response.status"></a-input>
</a-form-item>
<a-form-item label="响应状态说明">
<a-input v-model.trim="inModal.inbound.stream.tcp.response.reason"></a-input>
</a-form-item>
<a-form-item label="响应头">
<a-row>
<a-button size="small"
@click="inModal.inbound.stream.tcp.response.addHeader('Content-Type', 'application/octet-stream')">
+
</a-button>
</a-row>
<a-input-group v-for="(header, index) in inModal.inbound.stream.tcp.response.headers">
<a-input style="width: 50%" v-model.trim="header.name"
addon-before="名称"></a-input>
<a-input style="width: 50%" v-model.trim="header.value"
addon-before="值">
<template slot="addonAfter">
<a-button size="small"
@click="inModal.inbound.stream.tcp.response.removeHeader(index)">
-
</a-button>
</template>
</a-input>
</a-input-group>
</a-form-item>
</a-form>
</template>
<!-- vmess kcp -->
<a-form v-if="inModal.inbound.stream.network === 'kcp'"
layout="inline">
<a-form-item label="伪装">
<a-select v-model="inModal.inbound.stream.kcp.type" style="width: 280px;">
<a-select-option value="none">nonenot camouflage</a-select-option>
<a-select-option value="srtp">srtpcamouflage video call</a-select-option>
<a-select-option value="utp">utpcamouflage BT download</a-select-option>
<a-select-option value="wechat-video">wechat-videocamouflage WeChat video</a-select-option>
<a-select-option value="dtls">dtlscamouflage DTLS 1.2 packages</a-select-option>
<a-select-option value="wireguard">wireguardcamouflage wireguard packages</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="密码">
<a-input v-model.number="inModal.inbound.stream.kcp.seed"></a-input>
</a-form-item>
<a-form-item label="mtu">
<a-input type="number" v-model.number="inModal.inbound.stream.kcp.mtu"></a-input>
</a-form-item>
<a-form-item label="tti (ms)">
<a-input type="number" v-model.number="inModal.inbound.stream.kcp.tti"></a-input>
</a-form-item>
<a-form-item label="uplink capacity (MB/S)">
<a-input type="number" v-model.number="inModal.inbound.stream.kcp.upCap"></a-input>
</a-form-item>
<a-form-item label="downlink capacity (MB/S)">
<a-input type="number" v-model.number="inModal.inbound.stream.kcp.downCap"></a-input>
</a-form-item>
<a-form-item label="congestion">
<a-switch v-model="inModal.inbound.stream.kcp.congestion"></a-switch>
</a-form-item>
<a-form-item label="read buffer size (MB)">
<a-input type="number" v-model.number="inModal.inbound.stream.kcp.readBuffer"></a-input>
</a-form-item>
<a-form-item label="write buffer size (MB)">
<a-input type="number" v-model.number="inModal.inbound.stream.kcp.writeBuffer"></a-input>
</a-form-item>
</a-form>
<!-- vmess ws -->
<a-form v-if="inModal.inbound.stream.network === 'ws'"
layout="inline">
<a-form-item label="路径">
<a-input v-model.trim="inModal.inbound.stream.ws.path"></a-input>
</a-form-item>
<a-form-item label="请求头">
<a-row>
<a-button size="small"
@click="inModal.inbound.stream.ws.addHeader('Host', '')">
+
</a-button>
</a-row>
<a-input-group v-for="(header, index) in inModal.inbound.stream.ws.headers">
<a-input style="width: 50%" v-model.trim="header.name"
addon-before="名称"></a-input>
<a-input style="width: 50%" v-model.trim="header.value"
addon-before="值">
<template slot="addonAfter">
<a-button size="small"
@click="inModal.inbound.stream.ws.removeHeader(index)">
-
</a-button>
</template>
</a-input>
</a-input-group>
</a-form-item>
</a-form>
<!-- vmess http -->
<a-form v-if="inModal.inbound.stream.network === 'http'"
layout="inline">
<a-form-item label="路径">
<a-input v-model.trim="inModal.inbound.stream.http.path"></a-input>
</a-form-item>
<a-form-item label="host">
<a-row v-for="(host, index) in inModal.inbound.stream.http.host">
<a-input v-model.trim="inModal.inbound.stream.http.host[index]"></a-input>
</a-row>
</a-form-item>
</a-form>
<!-- vmess quic -->
<a-form v-if="inModal.inbound.stream.network === 'quic'"
layout="inline">
<a-form-item label="加密">
<a-select v-model="inModal.inbound.stream.quic.security" style="width: 165px;">
<a-select-option value="none">none</a-select-option>
<a-select-option value="aes-128-gcm">aes-128-gcm</a-select-option>
<a-select-option value="chacha20-poly1305">chacha20-poly1305</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="密码">
<a-input v-model.trim="inModal.inbound.stream.quic.key"></a-input>
</a-form-item>
<a-form-item label="伪装">
<a-select v-model="inModal.inbound.stream.quic.type" style="width: 280px;">
<a-select-option value="none">nonenot camouflage</a-select-option>
<a-select-option value="srtp">srtpcamouflage video call</a-select-option>
<a-select-option value="utp">utpcamouflage BT download</a-select-option>
<a-select-option value="wechat-video">wechat-videocamouflage WeChat video</a-select-option>
<a-select-option value="dtls">dtlscamouflage DTLS 1.2 packages</a-select-option>
<a-select-option value="wireguard">wireguardcamouflage wireguard packages</a-select-option>
</a-select>
</a-form-item>
</a-form>
</template>
<!-- dokodemo-door -->
<a-form v-if="inModal.inbound.protocol === Protocols.DOKODEMO"
layout="inline">
<a-form-item label="目标地址">
<a-input v-model.trim="inModal.inbound.settings.address"></a-input>
</a-form-item>
<a-form-item label="目标端口">
<a-input type="number" v-model.number="inModal.inbound.settings.port"></a-input>
</a-form-item>
<a-form-item label="网络">
<a-select v-model="inModal.inbound.settings.network" style="width: 100px;">
<a-select-option value="tcp,udp">tcp+udp</a-select-option>
<a-select-option value="tcp">tcp</a-select-option>
<a-select-option value="udp">udp</a-select-option>
</a-select>
</a-form-item>
</a-form>
<!-- socks -->
<a-form v-if="inModal.inbound.protocol === Protocols.SOCKS"
layout="inline">
<a-form-item label="密码认证">
<a-switch :checked="inModal.inbound.settings.auth === 'password'"
@change="checked => inModal.inbound.settings.auth = checked ? 'password' : 'noauth'"></a-switch>
</a-form-item>
<template v-if="inModal.inbound.settings.auth === 'password'">
<a-form-item label="用户名">
<a-input v-model.trim="inModal.inbound.settings.accounts[0].user"></a-input>
</a-form-item>
<a-form-item label="密码">
<a-input v-model.trim="inModal.inbound.settings.accounts[0].pass"></a-input>
</a-form-item>
</template>
<a-form-item label="启用 udp">
<a-switch v-model="inModal.inbound.settings.udp"></a-switch>
</a-form-item>
<a-form-item v-if="inModal.inbound.settings.udp"
label="IP">
<a-input v-model.trim="inModal.inbound.settings.ip"></a-input>
</a-form-item>
</a-form>
<!-- http -->
<a-form v-if="inModal.inbound.protocol === Protocols.HTTP"
layout="inline">
<a-form-item label="用户名">
<a-input v-model.trim="inModal.inbound.settings.accounts[0].user"></a-input>
</a-form-item>
<a-form-item label="密码">
<a-input v-model.trim="inModal.inbound.settings.accounts[0].pass"></a-input>
</a-form-item>
</a-form>
<!-- tls settings -->
<template v-if="(inModal.inbound.protocol === Protocols.VMESS
|| inModal.inbound.protocol === Protocols.VLESS
|| inModal.inbound.protocol === Protocols.TROJAN
|| inModal.inbound.protocol === Protocols.SHADOWSOCKS)
&& ['tcp', 'ws', 'http', 'quic'].indexOf(inModal.inbound.stream.network) >= 0">
<!-- tls enable -->
<a-form layout="inline" v-if="inModal.inbound.protocol !== Protocols.TROJAN">
<a-form-item label="tls">
<a-switch
:checked="inModal.inbound.stream.security === 'tls'"
@change="checked => inModal.inbound.stream.security = checked ? 'tls' : 'none'">
</a-switch>
</a-form-item>
<a-form-item v-if="inModal.inbound.protocol === Protocols.VLESS && inModal.inbound.stream.security === 'tls' && inModal.inbound.stream.network === 'tcp'" label="xtls">
<a-switch v-model="inModal.inbound.stream.is_xtls"></a-switch>
</a-form-item>
</a-form>
<!-- tls settings -->
<a-form v-if="inModal.inbound.stream.security === 'tls'"
layout="inline">
<a-form-item label="域名">
<a-input v-model.trim="inModal.inbound.stream.tls.server"></a-input>
</a-form-item>
{# <a-form-item label="允许不安全">#}
{# <a-switch v-model="inModal.inbound.stream.tls.allowInsecure"></a-switch>#}
{# </a-form-item>#}
<a-form-item label="证书">
<a-radio-group v-model="inModal.inbound.stream.tls.certs[0].useFile"
button-style="solid">
<a-radio-button :value="true">certificate file path</a-radio-button>
<a-radio-button :value="false">certificate file content</a-radio-button>
</a-radio-group>
</a-form-item>
<template v-if="inModal.inbound.stream.tls.certs[0].useFile">
<a-form-item label="公钥文件路径">
<a-input v-model.trim="inModal.inbound.stream.tls.certs[0].certFile"></a-input>
</a-form-item>
<a-form-item label="密钥文件路径">
<a-input v-model.trim="inModal.inbound.stream.tls.certs[0].keyFile"></a-input>
</a-form-item>
</template>
<template v-else>
<a-form-item label="公钥内容">
<a-input type="textarea" :rows="2"
v-model="inModal.inbound.stream.tls.certs[0].cert"></a-input>
</a-form-item>
<a-form-item label="密钥内容">
<a-input type="textarea" :rows="2"
v-model="inModal.inbound.stream.tls.certs[0].key"></a-input>
</a-form-item>
</template>
</a-form>
</template>
<!-- sniffing -->
<a-form layout="inline">
<a-form-item>
<span slot="label">
sniffing
<a-tooltip>
<template slot="title">
没有特殊需求保持默认即可
</template>
<a-icon type="question-circle" theme="filled"></a-icon>
</a-tooltip>
</span>
<a-switch v-model="inModal.inbound.sniffing.enabled"></a-switch>
</a-form-item>
</a-form>
</a-modal>
<script>
const inModal = {
title: '',
visible: false,
confirmLoading: false,
okText: '确定',
confirm: null,
inbound: new Inbound(),
ok() {
ObjectUtil.execute(inModal.confirm);
},
show({ title='', okText='确定', inbound=null, confirm=()=>{} }) {
this.title = title;
this.okText = okText;
if (inbound) {
this.inbound = Inbound.fromJson(inbound.toJson());
} else {
this.inbound = new Inbound();
}
this.confirm = confirm;
this.visible = true;
},
close() {
inModal.visible = false;
inModal.closeLoading();
},
loading() {
inModal.confirmLoading = true;
},
closeLoading() {
inModal.confirmLoading = false;
}
};
const protocols = {
VMESS: Protocols.VMESS,
VLESS: Protocols.VLESS,
TROJAN: Protocols.TROJAN,
SHADOWSOCKS: Protocols.SHADOWSOCKS,
DOKODEMO: Protocols.DOKODEMO,
SOCKS: Protocols.SOCKS,
HTTP: Protocols.HTTP,
};
new Vue({
delimiters: ['[[', ']]'],
el: '#inbound-modal',
data: {
inModal: inModal,
Protocols: protocols,
SSMethods: SSMethods,
},
methods: {
streamNetworkChange(oldValue) {
if (oldValue === 'kcp') {
this.inModal.inbound.stream.security = 'none';
}
},
protocolChange(value) {
this.inModal.inbound.settings = Inbound.Settings.getSettings(value);
if (value === Protocols.TROJAN) {
this.inModal.inbound.stream.security = 'tls';
}
}
}
});
</script>
{{end}}