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

github.com/MHSanaei/3x-ui.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'web/html/xray.html')
-rw-r--r--web/html/xray.html1130
1 files changed, 820 insertions, 310 deletions
diff --git a/web/html/xray.html b/web/html/xray.html
index 61c40c80..e229350d 100644
--- a/web/html/xray.html
+++ b/web/html/xray.html
@@ -1,10 +1,7 @@
{{ template "page/head_start" .}}
-<link rel="stylesheet"
- href="{{ .base_path }}assets/codemirror/codemirror.min.css?{{ .cur_ver }}">
-<link rel="stylesheet"
- href="{{ .base_path }}assets/codemirror/fold/foldgutter.css">
-<link rel="stylesheet"
- href="{{ .base_path }}assets/codemirror/xq.min.css?{{ .cur_ver }}">
+<link rel="stylesheet" href="{{ .base_path }}assets/codemirror/codemirror.min.css?{{ .cur_ver }}">
+<link rel="stylesheet" href="{{ .base_path }}assets/codemirror/fold/foldgutter.css">
+<link rel="stylesheet" href="{{ .base_path }}assets/codemirror/xq.min.css?{{ .cur_ver }}">
<link rel="stylesheet" href="{{ .base_path }}assets/codemirror/lint/lint.css">
{{ template "page/head_end" .}}
@@ -13,13 +10,10 @@
<a-sidebar></a-sidebar>
<a-layout id="content-layout">
<a-layout-content>
- <a-spin :spinning="loadingStates.spinning" :delay="500"
- tip='{{ i18n "loading"}}' size="large">
+ <a-spin :spinning="loadingStates.spinning" :delay="500" tip='{{ i18n "loading"}}' size="large">
<transition name="list" appear>
- <a-alert type="error" v-if="showAlert && loadingStates.fetched"
- :style="{ marginBottom: '10px' }"
- message='{{ i18n "secAlertTitle" }}' color="red"
- description='{{ i18n "secAlertSsl" }}' show-icon closable>
+ <a-alert type="error" v-if="showAlert && loadingStates.fetched" :style="{ marginBottom: '10px' }"
+ message='{{ i18n "secAlertTitle" }}' color="red" description='{{ i18n "secAlertSsl" }}' show-icon closable>
</a-alert>
</transition>
<transition name="list" appear>
@@ -29,25 +23,20 @@
<a-row :gutter="[isMobile ? 8 : 16, isMobile ? 0 : 12]" v-else>
<a-col>
<a-card hoverable>
- <a-row
- :style="{ display: 'flex', flexWrap: 'wrap', alignItems: 'center' }">
+ <a-row :style="{ display: 'flex', flexWrap: 'wrap', alignItems: 'center' }">
<a-col :xs="24" :sm="10" :style="{ padding: '4px' }">
<a-space direction="horizontal">
- <a-button type="primary" :disabled="saveBtnDisable"
- @click="updateXraySetting">
+ <a-button type="primary" :disabled="saveBtnDisable" @click="updateXraySetting">
{{ i18n "pages.xray.save" }}
</a-button>
- <a-button type="danger" :disabled="!saveBtnDisable"
- @click="restartXray">
+ <a-button type="danger" :disabled="!saveBtnDisable" @click="restartXray">
{{ i18n "pages.xray.restart" }}
</a-button>
- <a-popover v-if="restartResult"
- :overlay-class-name="themeSwitcher.currentTheme">
+ <a-popover v-if="restartResult" :overlay-class-name="themeSwitcher.currentTheme">
<span slot="title">{{ i18n
"pages.index.xrayErrorPopoverTitle" }}</span>
<template slot="content">
- <span :style="{ maxWidth: '400px' }"
- v-for="line in restartResult.split('\n')">[[ line
+ <span :style="{ maxWidth: '400px' }" v-for="line in restartResult.split('\n')">[[ line
]]</span>
</template>
<a-icon type="question-circle"></a-icon>
@@ -57,13 +46,10 @@
<a-col :xs="24" :sm="14">
<template>
<div>
- <a-back-top
- :target="() => document.getElementById('content-layout')"
+ <a-back-top :target="() => document.getElementById('content-layout')"
visibility-height="200"></a-back-top>
- <a-alert type="warning"
- :style="{ float: 'right', width: 'fit-content' }"
- message='{{ i18n "pages.settings.infoDesc" }}'
- show-icon>
+ <a-alert type="warning" :style="{ float: 'right', width: 'fit-content' }"
+ message='{{ i18n "pages.settings.infoDesc" }}' show-icon>
</a-alert>
</div>
</template>
@@ -72,8 +58,7 @@
</a-card>
</a-col>
<a-col>
- <a-tabs default-active-key="tpl-basic"
- @change="(activeKey) => { this.changePage(activeKey); }"
+ <a-tabs default-active-key="tpl-basic" @change="(activeKey) => { this.changePage(activeKey); }"
:class="themeSwitcher.currentTheme">
<a-tab-pane key="tpl-basic" :style="{ paddingTop: '20px' }">
<template #tab>
@@ -96,24 +81,21 @@
</template>
{{ template "settings/xray/outbounds" . }}
</a-tab-pane>
- <a-tab-pane key="tpl-reverse" :style="{ paddingTop: '20px' }"
- force-render="true">
+ <a-tab-pane key="tpl-reverse" :style="{ paddingTop: '20px' }" force-render="true">
<template #tab>
<a-icon type="import"></a-icon>
<span>{{ i18n "pages.xray.outbound.reverse"}}</span>
</template>
{{ template "settings/xray/reverse" . }}
</a-tab-pane>
- <a-tab-pane key="tpl-balancer" :style="{ paddingTop: '20px' }"
- force-render="true">
+ <a-tab-pane key="tpl-balancer" :style="{ paddingTop: '20px' }" force-render="true">
<template #tab>
<a-icon type="cluster"></a-icon>
<span>{{ i18n "pages.xray.Balancers"}}</span>
</template>
{{ template "settings/xray/balancers" . }}
</a-tab-pane>
- <a-tab-pane key="tpl-dns" :style="{ paddingTop: '20px' }"
- force-render="true">
+ <a-tab-pane key="tpl-dns" :style="{ paddingTop: '20px' }" force-render="true">
<template #tab>
<a-icon type="database"></a-icon>
<span>DNS</span>
@@ -136,18 +118,14 @@
</a-layout>
</a-layout>
{{template "page/body_scripts" .}}
-<script
- src="{{ .base_path }}assets/js/model/outbound.js?{{ .cur_ver }}"></script>
-<script
- src="{{ .base_path }}assets/codemirror/codemirror.min.js?{{ .cur_ver }}"></script>
+<script src="{{ .base_path }}assets/js/model/outbound.js?{{ .cur_ver }}"></script>
+<script src="{{ .base_path }}assets/codemirror/codemirror.min.js?{{ .cur_ver }}"></script>
<script src="{{ .base_path }}assets/codemirror/javascript.js"></script>
<script src="{{ .base_path }}assets/codemirror/jshint.js"></script>
<script src="{{ .base_path }}assets/codemirror/jsonlint.js"></script>
<script src="{{ .base_path }}assets/codemirror/lint/lint.js"></script>
-<script
- src="{{ .base_path }}assets/codemirror/lint/javascript-lint.js"></script>
-<script
- src="{{ .base_path }}assets/codemirror/hint/javascript-hint.js"></script>
+<script src="{{ .base_path }}assets/codemirror/lint/javascript-lint.js"></script>
+<script src="{{ .base_path }}assets/codemirror/hint/javascript-hint.js"></script>
<script src="{{ .base_path }}assets/codemirror/fold/foldcode.js"></script>
<script src="{{ .base_path }}assets/codemirror/fold/foldgutter.js"></script>
<script src="{{ .base_path }}assets/codemirror/fold/brace-fold.js"></script>
@@ -165,77 +143,327 @@
{{template "modals/warpModal"}}
{{template "modals/nordModal"}}
<script>
- const rulesColumns = [
- { title: "#", align: 'center', width: 15, scopedSlots: { customRender: 'action' } },
+ const rulesColumns = [{
+ title: "#",
+ align: 'center',
+ width: 15,
+ scopedSlots: {
+ customRender: 'action'
+ }
+ },
+ {
+ title: '{{ i18n "pages.xray.rules.source"}}',
+ children: [{
+ title: 'IP',
+ dataIndex: "sourceIP",
+ align: 'center',
+ width: 20,
+ ellipsis: true
+ },
+ {
+ title: '{{ i18n "pages.inbounds.port" }}',
+ dataIndex: 'sourcePort',
+ align: 'center',
+ width: 10,
+ ellipsis: true
+ },
+ {
+ title: 'VLESS Route',
+ dataIndex: 'vlessRoute',
+ align: 'center',
+ width: 15,
+ ellipsis: true
+ }
+ ]
+ },
{
- title: '{{ i18n "pages.xray.rules.source"}}', children: [
- { title: 'IP', dataIndex: "sourceIP", align: 'center', width: 20, ellipsis: true },
- { title: '{{ i18n "pages.inbounds.port" }}', dataIndex: 'sourcePort', align: 'center', width: 10, ellipsis: true },
- { title: 'VLESS Route', dataIndex: 'vlessRoute', align: 'center', width: 15, ellipsis: true }]
+ title: '{{ i18n "pages.inbounds.network"}}',
+ children: [{
+ title: 'L4',
+ dataIndex: 'network',
+ align: 'center',
+ width: 10
+ },
+ {
+ title: '{{ i18n "protocol" }}',
+ dataIndex: 'protocol',
+ align: 'center',
+ width: 15,
+ ellipsis: true
+ },
+ {
+ title: 'Attrs',
+ dataIndex: 'attrs',
+ align: 'center',
+ width: 10,
+ ellipsis: true
+ }
+ ]
},
{
- title: '{{ i18n "pages.inbounds.network"}}', children: [
- { title: 'L4', dataIndex: 'network', align: 'center', width: 10 },
- { title: '{{ i18n "protocol" }}', dataIndex: 'protocol', align: 'center', width: 15, ellipsis: true },
- { title: 'Attrs', dataIndex: 'attrs', align: 'center', width: 10, ellipsis: true }]
+ title: '{{ i18n "pages.xray.rules.dest"}}',
+ children: [{
+ title: 'IP',
+ dataIndex: 'ip',
+ align: 'center',
+ width: 20,
+ ellipsis: true
+ },
+ {
+ title: '{{ i18n "pages.xray.outbound.domain" }}',
+ dataIndex: 'domain',
+ align: 'center',
+ width: 20,
+ ellipsis: true
+ },
+ {
+ title: '{{ i18n "pages.inbounds.port" }}',
+ dataIndex: 'port',
+ align: 'center',
+ width: 10,
+ ellipsis: true
+ }
+ ]
},
{
- title: '{{ i18n "pages.xray.rules.dest"}}', children: [
- { title: 'IP', dataIndex: 'ip', align: 'center', width: 20, ellipsis: true },
- { title: '{{ i18n "pages.xray.outbound.domain" }}', dataIndex: 'domain', align: 'center', width: 20, ellipsis: true },
- { title: '{{ i18n "pages.inbounds.port" }}', dataIndex: 'port', align: 'center', width: 10, ellipsis: true }]
+ title: '{{ i18n "pages.xray.rules.inbound"}}',
+ children: [{
+ title: '{{ i18n "pages.xray.outbound.tag" }}',
+ dataIndex: 'inboundTag',
+ align: 'center',
+ width: 15,
+ ellipsis: true
+ },
+ {
+ title: '{{ i18n "pages.inbounds.client" }}',
+ dataIndex: 'user',
+ align: 'center',
+ width: 20,
+ ellipsis: true
+ }
+ ]
},
{
- title: '{{ i18n "pages.xray.rules.inbound"}}', children: [
- { title: '{{ i18n "pages.xray.outbound.tag" }}', dataIndex: 'inboundTag', align: 'center', width: 15, ellipsis: true },
- { title: '{{ i18n "pages.inbounds.client" }}', dataIndex: 'user', align: 'center', width: 20, ellipsis: true }]
+ title: '{{ i18n "pages.xray.rules.outbound"}}',
+ dataIndex: 'outboundTag',
+ align: 'center',
+ width: 17
+ },
+ {
+ title: '{{ i18n "pages.xray.rules.balancer"}}',
+ dataIndex: 'balancerTag',
+ align: 'center',
+ width: 15
},
- { title: '{{ i18n "pages.xray.rules.outbound"}}', dataIndex: 'outboundTag', align: 'center', width: 17 },
- { title: '{{ i18n "pages.xray.rules.balancer"}}', dataIndex: 'balancerTag', align: 'center', width: 15 },
];
- const rulesMobileColumns = [
- { title: "#", align: 'center', width: 20, scopedSlots: { customRender: 'action' } },
- { title: '{{ i18n "pages.xray.rules.inbound"}}', align: 'center', width: 50, ellipsis: true, scopedSlots: { customRender: 'inbound' } },
- { title: '{{ i18n "pages.xray.rules.outbound"}}', align: 'center', width: 50, ellipsis: true, scopedSlots: { customRender: 'outbound' } },
- { title: '{{ i18n "pages.xray.rules.info"}}', align: 'center', width: 50, ellipsis: true, scopedSlots: { customRender: 'info' } },
+ const rulesMobileColumns = [{
+ title: "#",
+ align: 'center',
+ width: 20,
+ scopedSlots: {
+ customRender: 'action'
+ }
+ },
+ {
+ title: '{{ i18n "pages.xray.rules.inbound"}}',
+ align: 'center',
+ width: 50,
+ ellipsis: true,
+ scopedSlots: {
+ customRender: 'inbound'
+ }
+ },
+ {
+ title: '{{ i18n "pages.xray.rules.outbound"}}',
+ align: 'center',
+ width: 50,
+ ellipsis: true,
+ scopedSlots: {
+ customRender: 'outbound'
+ }
+ },
+ {
+ title: '{{ i18n "pages.xray.rules.info"}}',
+ align: 'center',
+ width: 50,
+ ellipsis: true,
+ scopedSlots: {
+ customRender: 'info'
+ }
+ },
];
- const outboundColumns = [
- { title: "#", align: 'center', width: 60, scopedSlots: { customRender: 'action' } },
- { title: '{{ i18n "pages.xray.outbound.tag"}}', dataIndex: 'tag', align: 'center', width: 50 },
- { title: '{{ i18n "protocol"}}', align: 'center', width: 50, scopedSlots: { customRender: 'protocol' } },
- { title: '{{ i18n "pages.xray.outbound.address"}}', align: 'center', width: 50, scopedSlots: { customRender: 'address' } },
- { title: '{{ i18n "pages.inbounds.traffic" }}', align: 'center', width: 50, scopedSlots: { customRender: 'traffic' } },
- { title: '{{ i18n "pages.xray.outbound.testResult" }}', align: 'center', width: 120, scopedSlots: { customRender: 'testResult' } },
- { title: '{{ i18n "pages.xray.outbound.test" }}', align: 'center', width: 60, scopedSlots: { customRender: 'test' } },
+ const outboundColumns = [{
+ title: "#",
+ align: 'center',
+ width: 60,
+ scopedSlots: {
+ customRender: 'action'
+ }
+ },
+ {
+ title: '{{ i18n "pages.xray.outbound.tag"}}',
+ dataIndex: 'tag',
+ align: 'center',
+ width: 50
+ },
+ {
+ title: '{{ i18n "protocol"}}',
+ align: 'center',
+ width: 50,
+ scopedSlots: {
+ customRender: 'protocol'
+ }
+ },
+ {
+ title: '{{ i18n "pages.xray.outbound.address"}}',
+ align: 'center',
+ width: 50,
+ scopedSlots: {
+ customRender: 'address'
+ }
+ },
+ {
+ title: '{{ i18n "pages.inbounds.traffic" }}',
+ align: 'center',
+ width: 50,
+ scopedSlots: {
+ customRender: 'traffic'
+ }
+ },
+ {
+ title: '{{ i18n "pages.xray.outbound.testResult" }}',
+ align: 'center',
+ width: 120,
+ scopedSlots: {
+ customRender: 'testResult'
+ }
+ },
+ {
+ title: '{{ i18n "pages.xray.outbound.test" }}',
+ align: 'center',
+ width: 60,
+ scopedSlots: {
+ customRender: 'test'
+ }
+ },
];
- const reverseColumns = [
- { title: "#", align: 'center', width: 20, scopedSlots: { customRender: 'action' } },
- { title: '{{ i18n "pages.xray.outbound.type"}}', dataIndex: 'type', align: 'center', width: 50 },
- { title: '{{ i18n "pages.xray.outbound.tag"}}', dataIndex: 'tag', align: 'center', width: 50 },
- { title: '{{ i18n "pages.xray.outbound.domain"}}', dataIndex: 'domain', align: 'center', width: 50 },
+ const reverseColumns = [{
+ title: "#",
+ align: 'center',
+ width: 20,
+ scopedSlots: {
+ customRender: 'action'
+ }
+ },
+ {
+ title: '{{ i18n "pages.xray.outbound.type"}}',
+ dataIndex: 'type',
+ align: 'center',
+ width: 50
+ },
+ {
+ title: '{{ i18n "pages.xray.outbound.tag"}}',
+ dataIndex: 'tag',
+ align: 'center',
+ width: 50
+ },
+ {
+ title: '{{ i18n "pages.xray.outbound.domain"}}',
+ dataIndex: 'domain',
+ align: 'center',
+ width: 50
+ },
];
- const balancerColumns = [
- { title: "#", align: 'center', width: 20, scopedSlots: { customRender: 'action' } },
- { title: '{{ i18n "pages.xray.balancer.tag"}}', dataIndex: 'tag', align: 'center', width: 50 },
- { title: '{{ i18n "pages.xray.balancer.balancerStrategy"}}', align: 'center', width: 50, scopedSlots: { customRender: 'strategy' } },
- { title: '{{ i18n "pages.xray.balancer.balancerSelectors"}}', align: 'center', width: 100, scopedSlots: { customRender: 'selector' } },
+ const balancerColumns = [{
+ title: "#",
+ align: 'center',
+ width: 20,
+ scopedSlots: {
+ customRender: 'action'
+ }
+ },
+ {
+ title: '{{ i18n "pages.xray.balancer.tag"}}',
+ dataIndex: 'tag',
+ align: 'center',
+ width: 50
+ },
+ {
+ title: '{{ i18n "pages.xray.balancer.balancerStrategy"}}',
+ align: 'center',
+ width: 50,
+ scopedSlots: {
+ customRender: 'strategy'
+ }
+ },
+ {
+ title: '{{ i18n "pages.xray.balancer.balancerSelectors"}}',
+ align: 'center',
+ width: 100,
+ scopedSlots: {
+ customRender: 'selector'
+ }
+ },
];
- const dnsColumns = [
- { title: "#", align: 'center', width: 20, scopedSlots: { customRender: 'action' } },
- { title: '{{ i18n "pages.xray.outbound.address"}}', align: 'center', width: 50, scopedSlots: { customRender: 'address' } },
- { title: '{{ i18n "pages.xray.dns.domains"}}', align: 'center', width: 50, scopedSlots: { customRender: 'domain' } },
- { title: '{{ i18n "pages.xray.dns.expectIPs"}}', align: 'center', width: 50, scopedSlots: { customRender: 'expectIPs' } },
+ const dnsColumns = [{
+ title: "#",
+ align: 'center',
+ width: 20,
+ scopedSlots: {
+ customRender: 'action'
+ }
+ },
+ {
+ title: '{{ i18n "pages.xray.outbound.address"}}',
+ align: 'center',
+ width: 50,
+ scopedSlots: {
+ customRender: 'address'
+ }
+ },
+ {
+ title: '{{ i18n "pages.xray.dns.domains"}}',
+ align: 'center',
+ width: 50,
+ scopedSlots: {
+ customRender: 'domain'
+ }
+ },
+ {
+ title: '{{ i18n "pages.xray.dns.expectIPs"}}',
+ align: 'center',
+ width: 50,
+ scopedSlots: {
+ customRender: 'expectIPs'
+ }
+ },
];
- const fakednsColumns = [
- { title: "#", align: 'center', width: 20, scopedSlots: { customRender: 'action' } },
- { title: '{{ i18n "pages.xray.fakedns.ipPool"}}', dataIndex: 'ipPool', align: 'center', width: 50 },
- { title: '{{ i18n "pages.xray.fakedns.poolSize"}}', dataIndex: 'poolSize', align: 'center', width: 50 },
+ const fakednsColumns = [{
+ title: "#",
+ align: 'center',
+ width: 20,
+ scopedSlots: {
+ customRender: 'action'
+ }
+ },
+ {
+ title: '{{ i18n "pages.xray.fakedns.ipPool"}}',
+ dataIndex: 'ipPool',
+ align: 'center',
+ width: 50
+ },
+ {
+ title: '{{ i18n "pages.xray.fakedns.poolSize"}}',
+ dataIndex: 'poolSize',
+ align: 'center',
+ width: 50
+ },
];
const app = new Vue({
@@ -308,58 +536,189 @@
protocols: {
bittorrent: ["bittorrent"],
},
- IPsOptions: [
- { label: 'Private IPs', value: 'geoip:private' },
- { label: '🇮🇷 Iran', value: 'ext:geoip_IR.dat:ir' },
- { label: '🇨🇳 China', value: 'geoip:cn' },
- { label: '🇷🇺 Russia', value: 'ext:geoip_RU.dat:ru' },
- { label: '🇻🇳 Vietnam', value: 'geoip:vn' },
- { label: '🇪🇸 Spain', value: 'geoip:es' },
- { label: '🇮🇩 Indonesia', value: 'geoip:id' },
- { label: '🇺🇦 Ukraine', value: 'geoip:ua' },
- { label: '🇹🇷 Türkiye', value: 'geoip:tr' },
- { label: '🇧🇷 Brazil', value: 'geoip:br' },
+ IPsOptions: [{
+ label: 'Private IPs',
+ value: 'geoip:private'
+ },
+ {
+ label: '🇮🇷 Iran',
+ value: 'ext:geoip_IR.dat:ir'
+ },
+ {
+ label: '🇨🇳 China',
+ value: 'geoip:cn'
+ },
+ {
+ label: '🇷🇺 Russia',
+ value: 'ext:geoip_RU.dat:ru'
+ },
+ {
+ label: '🇻🇳 Vietnam',
+ value: 'geoip:vn'
+ },
+ {
+ label: '🇪🇸 Spain',
+ value: 'geoip:es'
+ },
+ {
+ label: '🇮🇩 Indonesia',
+ value: 'geoip:id'
+ },
+ {
+ label: '🇺🇦 Ukraine',
+ value: 'geoip:ua'
+ },
+ {
+ label: '🇹🇷 Türkiye',
+ value: 'geoip:tr'
+ },
+ {
+ label: '🇧🇷 Brazil',
+ value: 'geoip:br'
+ },
],
- DomainsOptions: [
- { label: '🇮🇷 Iran', value: 'ext:geosite_IR.dat:ir' },
- { label: '🇮🇷 .ir', value: 'regexp:.*\\.ir$' },
- { label: '🇮🇷 .ایران', value: 'regexp:.*\\.xn--mgba3a4f16a$' },
- { label: '🇨🇳 China', value: 'geosite:cn' },
- { label: '🇨🇳 .cn', value: 'regexp:.*\\.cn$' },
- { label: '🇷🇺 Russia', value: 'ext:geosite_RU.dat:ru-available-only-inside' },
- { label: '🇷🇺 .ru', value: 'regexp:.*\\.ru$' },
- { label: '🇷🇺 .su', value: 'regexp:.*\\.su$' },
- { label: '🇷🇺 .рф', value: 'regexp:.*\\.xn--p1ai$' },
- { label: '🇻🇳 .vn', value: 'regexp:.*\\.vn$' },
+ DomainsOptions: [{
+ label: '🇮🇷 Iran',
+ value: 'ext:geosite_IR.dat:ir'
+ },
+ {
+ label: '🇮🇷 .ir',
+ value: 'regexp:.*\\.ir$'
+ },
+ {
+ label: '🇮🇷 .ایران',
+ value: 'regexp:.*\\.xn--mgba3a4f16a$'
+ },
+ {
+ label: '🇨🇳 China',
+ value: 'geosite:cn'
+ },
+ {
+ label: '🇨🇳 .cn',
+ value: 'regexp:.*\\.cn$'
+ },
+ {
+ label: '🇷🇺 Russia',
+ value: 'ext:geosite_RU.dat:ru-available-only-inside'
+ },
+ {
+ label: '🇷🇺 .ru',
+ value: 'regexp:.*\\.ru$'
+ },
+ {
+ label: '🇷🇺 .su',
+ value: 'regexp:.*\\.su$'
+ },
+ {
+ label: '🇷🇺 .рф',
+ value: 'regexp:.*\\.xn--p1ai$'
+ },
+ {
+ label: '🇻🇳 .vn',
+ value: 'regexp:.*\\.vn$'
+ },
],
- BlockDomainsOptions: [
- { label: 'Ads All', value: 'geosite:category-ads-all' },
- { label: 'Ads IR 🇮🇷', value: 'ext:geosite_IR.dat:category-ads-all' },
- { label: 'Ads RU 🇷🇺', value: 'ext:geosite_RU.dat:category-ads-all' },
- { label: 'Malware 🇮🇷', value: 'ext:geosite_IR.dat:malware' },
- { label: 'Phishing 🇮🇷', value: 'ext:geosite_IR.dat:phishing' },
- { label: 'Cryptominers 🇮🇷', value: 'ext:geosite_IR.dat:cryptominers' },
- { label: 'Adult +18', value: 'geosite:category-porn' },
- { label: '🇮🇷 Iran', value: 'ext:geosite_IR.dat:ir' },
- { label: '🇮🇷 .ir', value: 'regexp:.*\\.ir$' },
- { label: '🇮🇷 .ایران', value: 'regexp:.*\\.xn--mgba3a4f16a$' },
- { label: '🇨🇳 China', value: 'geosite:cn' },
- { label: '🇨🇳 .cn', value: 'regexp:.*\\.cn$' },
- { label: '🇷🇺 Russia', value: 'ext:geosite_RU.dat:ru-available-only-inside' },
- { label: '🇷🇺 .ru', value: 'regexp:.*\\.ru$' },
- { label: '🇷🇺 .su', value: 'regexp:.*\\.su$' },
- { label: '🇷🇺 .рф', value: 'regexp:.*\\.xn--p1ai$' },
- { label: '🇻🇳 .vn', value: 'regexp:.*\\.vn$' },
+ BlockDomainsOptions: [{
+ label: 'Ads All',
+ value: 'geosite:category-ads-all'
+ },
+ {
+ label: 'Ads IR 🇮🇷',
+ value: 'ext:geosite_IR.dat:category-ads-all'
+ },
+ {
+ label: 'Ads RU 🇷🇺',
+ value: 'ext:geosite_RU.dat:category-ads-all'
+ },
+ {
+ label: 'Malware 🇮🇷',
+ value: 'ext:geosite_IR.dat:malware'
+ },
+ {
+ label: 'Phishing 🇮🇷',
+ value: 'ext:geosite_IR.dat:phishing'
+ },
+ {
+ label: 'Cryptominers 🇮🇷',
+ value: 'ext:geosite_IR.dat:cryptominers'
+ },
+ {
+ label: 'Adult +18',
+ value: 'geosite:category-porn'
+ },
+ {
+ label: '🇮🇷 Iran',
+ value: 'ext:geosite_IR.dat:ir'
+ },
+ {
+ label: '🇮🇷 .ir',
+ value: 'regexp:.*\\.ir$'
+ },
+ {
+ label: '🇮🇷 .ایران',
+ value: 'regexp:.*\\.xn--mgba3a4f16a$'
+ },
+ {
+ label: '🇨🇳 China',
+ value: 'geosite:cn'
+ },
+ {
+ label: '🇨🇳 .cn',
+ value: 'regexp:.*\\.cn$'
+ },
+ {
+ label: '🇷🇺 Russia',
+ value: 'ext:geosite_RU.dat:ru-available-only-inside'
+ },
+ {
+ label: '🇷🇺 .ru',
+ value: 'regexp:.*\\.ru$'
+ },
+ {
+ label: '🇷🇺 .su',
+ value: 'regexp:.*\\.su$'
+ },
+ {
+ label: '🇷🇺 .рф',
+ value: 'regexp:.*\\.xn--p1ai$'
+ },
+ {
+ label: '🇻🇳 .vn',
+ value: 'regexp:.*\\.vn$'
+ },
],
- ServicesOptions: [
- { label: 'Apple', value: 'geosite:apple' },
- { label: 'Meta', value: 'geosite:meta' },
- { label: 'Google', value: 'geosite:google' },
- { label: 'OpenAI', value: 'geosite:openai' },
- { label: 'Spotify', value: 'geosite:spotify' },
- { label: 'Netflix', value: 'geosite:netflix' },
- { label: 'Reddit', value: 'geosite:reddit' },
- { label: 'Speedtest', value: 'geosite:speedtest' },
+ ServicesOptions: [{
+ label: 'Apple',
+ value: 'geosite:apple'
+ },
+ {
+ label: 'Meta',
+ value: 'geosite:meta'
+ },
+ {
+ label: 'Google',
+ value: 'geosite:google'
+ },
+ {
+ label: 'OpenAI',
+ value: 'geosite:openai'
+ },
+ {
+ label: 'Spotify',
+ value: 'geosite:spotify'
+ },
+ {
+ label: 'Netflix',
+ value: 'geosite:netflix'
+ },
+ {
+ label: 'Reddit',
+ value: 'geosite:reddit'
+ },
+ {
+ label: 'Speedtest',
+ value: 'geosite:speedtest'
+ },
]
},
defaultObservatory: {
@@ -461,7 +820,10 @@
this.templateSettings = newTemplateSettings;
},
templateRuleGetter(routeSettings) {
- const { property, outboundTag } = routeSettings;
+ const {
+ property,
+ outboundTag
+ } = routeSettings;
let result = [];
if (this.templateSettings != null) {
this.templateSettings.routing.rules.forEach(
@@ -479,10 +841,17 @@
return result;
},
templateRuleSetter(routeSettings) {
- const { data, property, outboundTag } = routeSettings;
+ const {
+ data,
+ property,
+ outboundTag
+ } = routeSettings;
const oldTemplateSettings = this.templateSettings;
const newTemplateSettings = oldTemplateSettings;
- currentProperty = this.templateRuleGetter({ outboundTag, property })
+ currentProperty = this.templateRuleGetter({
+ outboundTag,
+ property
+ })
if (currentProperty.length == 0) {
const propertyRule = {
type: "field",
@@ -490,8 +859,7 @@
[property]: data
};
newTemplateSettings.routing.rules.push(propertyRule);
- }
- else {
+ } else {
const newRules = [];
insertedOnce = false;
newTemplateSettings.routing.rules.forEach(
@@ -506,8 +874,7 @@
routingRule[property] = data;
newRules.push(routingRule);
}
- }
- else {
+ } else {
newRules.push(routingRule);
}
}
@@ -635,7 +1002,8 @@
}
if (outbound.protocol === 'blackhole' || outbound.tag === 'blocked') {
- Vue.prototype.$message.warning('{{ i18n "pages.xray.outbound.testError" }}: blocked/blackhole outbound');
+ Vue.prototype.$message.warning(
+ '{{ i18n "pages.xray.outbound.testError" }}: blocked/blackhole outbound');
return;
}
@@ -654,7 +1022,7 @@
try {
const outboundJSON = JSON.stringify(outbound);
const allOutboundsJSON = JSON.stringify(this.templateSettings.outbounds || []);
-
+
const msg = await HttpUtil.post("/panel/xray/testOutbound", {
outbound: outboundJSON,
allOutbounds: allOutboundsJSON
@@ -666,7 +1034,7 @@
if (msg.success && msg.obj) {
const result = msg.obj;
this.$set(this.outboundTestStates[index], 'result', result);
-
+
if (result.success) {
Vue.prototype.$message.success(
`{{ i18n "pages.xray.outbound.testSuccess" }}: ${result.delay}ms (${result.statusCode})`
@@ -701,8 +1069,12 @@
if (reverse.tag.length > 0) {
newTemplateSettings = this.templateSettings;
if (newTemplateSettings.reverse == undefined) newTemplateSettings.reverse = {};
- if (newTemplateSettings.reverse[reverse.type + 's'] == undefined) newTemplateSettings.reverse[reverse.type + 's'] = [];
- newTemplateSettings.reverse[reverse.type + 's'].push({ tag: reverse.tag, domain: reverse.domain });
+ if (newTemplateSettings.reverse[reverse.type + 's'] == undefined) newTemplateSettings.reverse[
+ reverse.type + 's'] = [];
+ newTemplateSettings.reverse[reverse.type + 's'].push({
+ tag: reverse.tag,
+ domain: reverse.domain
+ });
this.templateSettings = newTemplateSettings;
// Add related rules
@@ -716,9 +1088,11 @@
},
editReverse(index) {
if (this.reverseData[index].type == "bridge") {
- oldRules = this.templateSettings.routing.rules.filter(r => r.inboundTag && r.inboundTag[0] == this.reverseData[index].tag);
+ oldRules = this.templateSettings.routing.rules.filter(r => r.inboundTag && r.inboundTag[0] == this
+ .reverseData[index].tag);
} else {
- oldRules = this.templateSettings.routing.rules.filter(r => r.outboundTag && r.outboundTag == this.reverseData[index].tag);
+ oldRules = this.templateSettings.routing.rules.filter(r => r.outboundTag && r.outboundTag == this
+ .reverseData[index].tag);
}
reverseModal.show({
title: '{{ i18n "pages.xray.outbound.editReverse"}} ' + (index + 1),
@@ -729,18 +1103,29 @@
if (reverse.tag.length > 0) {
oldData = this.reverseData[index];
newTemplateSettings = this.templateSettings;
- oldReverseIndex = newTemplateSettings.reverse[oldData.type + 's'].findIndex(rs => rs.tag == oldData.tag);
- oldRuleIndex0 = oldRules.length > 0 ? newTemplateSettings.routing.rules.findIndex(r => JSON.stringify(r) == JSON.stringify(oldRules[0])) : -1;
- oldRuleIndex1 = oldRules.length == 2 ? newTemplateSettings.routing.rules.findIndex(r => JSON.stringify(r) == JSON.stringify(oldRules[1])) : -1;
+ oldReverseIndex = newTemplateSettings.reverse[oldData.type + 's'].findIndex(rs => rs.tag ==
+ oldData.tag);
+ oldRuleIndex0 = oldRules.length > 0 ? newTemplateSettings.routing.rules.findIndex(r => JSON
+ .stringify(r) == JSON.stringify(oldRules[0])) : -1;
+ oldRuleIndex1 = oldRules.length == 2 ? newTemplateSettings.routing.rules.findIndex(r => JSON
+ .stringify(r) == JSON.stringify(oldRules[1])) : -1;
if (oldData.type == reverse.type) {
- newTemplateSettings.reverse[oldData.type + 's'][oldReverseIndex] = { tag: reverse.tag, domain: reverse.domain };
+ newTemplateSettings.reverse[oldData.type + 's'][oldReverseIndex] = {
+ tag: reverse.tag,
+ domain: reverse.domain
+ };
} else {
newTemplateSettings.reverse[oldData.type + 's'].splice(oldReverseIndex, 1);
// delete empty object
- if (newTemplateSettings.reverse[oldData.type + 's'].length == 0) Reflect.deleteProperty(newTemplateSettings.reverse, oldData.type + 's');
+ if (newTemplateSettings.reverse[oldData.type + 's'].length == 0) Reflect.deleteProperty(
+ newTemplateSettings.reverse, oldData.type + 's');
// add other type of reverse if it is not exist
- if (!newTemplateSettings.reverse[reverse.type + 's']) newTemplateSettings.reverse[reverse.type + 's'] = [];
- newTemplateSettings.reverse[reverse.type + 's'].push({ tag: reverse.tag, domain: reverse.domain });
+ if (!newTemplateSettings.reverse[reverse.type + 's']) newTemplateSettings.reverse[reverse
+ .type + 's'] = [];
+ newTemplateSettings.reverse[reverse.type + 's'].push({
+ tag: reverse.tag,
+ domain: reverse.domain
+ });
}
this.templateSettings = newTemplateSettings;
@@ -764,12 +1149,14 @@
// delete empty objects
if (reverseTypeObj.length == 0) Reflect.deleteProperty(newTemplateSettings.reverse, oldData.type + 's');
- if (Object.keys(newTemplateSettings.reverse).length === 0) Reflect.deleteProperty(newTemplateSettings, 'reverse');
+ if (Object.keys(newTemplateSettings.reverse).length === 0) Reflect.deleteProperty(newTemplateSettings,
+ 'reverse');
// delete related routing rules
newRules = newTemplateSettings.routing.rules;
if (oldData.type == "bridge") {
- newRules = newTemplateSettings.routing.rules.filter(r => !(r.inboundTag && r.inboundTag.length == 1 && r.inboundTag[0] == oldData.tag));
+ newRules = newTemplateSettings.routing.rules.filter(r => !(r.inboundTag && r.inboundTag.length == 1 && r
+ .inboundTag[0] == oldData.tag));
} else if (oldData.type == "portal") {
newRules = newTemplateSettings.routing.rules.filter(r => r.outboundTag != oldData.tag);
}
@@ -785,7 +1172,10 @@
data = []
if (this.templateSettings != null) {
this.templateSettings.outbounds.forEach((o, index) => {
- data.push({ 'key': index, ...o });
+ data.push({
+ 'key': index,
+ ...o
+ });
});
}
@@ -798,7 +1188,9 @@
if (index >= 0) {
tag = this.outboundData[index].tag ? this.outboundData[index].tag : ""
}
- const msg = await HttpUtil.post("/panel/xray/resetOutboundsTraffic", { tag: tag });
+ const msg = await HttpUtil.post("/panel/xray/resetOutboundsTraffic", {
+ tag: tag
+ });
if (msg.success) {
await this.refreshOutboundTraffic();
}
@@ -858,10 +1250,12 @@
// Remove old tag
if (newTemplateSettings.observatory) {
- newTemplateSettings.observatory.subjectSelector = newTemplateSettings.observatory.subjectSelector.filter(s => s != oldTag);
+ newTemplateSettings.observatory.subjectSelector = newTemplateSettings.observatory
+ .subjectSelector.filter(s => s != oldTag);
}
if (newTemplateSettings.burstObservatory) {
- newTemplateSettings.burstObservatory.subjectSelector = newTemplateSettings.burstObservatory.subjectSelector.filter(s => s != oldTag);
+ newTemplateSettings.burstObservatory.subjectSelector = newTemplateSettings.burstObservatory
+ .subjectS