diff options
Diffstat (limited to 'web/html/xui/xray.html')
| -rw-r--r-- | web/html/xui/xray.html | 911 |
1 files changed, 911 insertions, 0 deletions
diff --git a/web/html/xui/xray.html b/web/html/xui/xray.html new file mode 100644 index 00000000..db5aa202 --- /dev/null +++ b/web/html/xui/xray.html @@ -0,0 +1,911 @@ +<!DOCTYPE html> +<html lang="en"> +{{template "head" .}} +<style> + @media (min-width: 769px) { + .ant-layout-content { + margin: 24px 16px; + } + } + + @media (max-width: 768px) { + .ant-tabs-nav .ant-tabs-tab { + margin: 0; + padding: 12px .5rem; + } + } + + .ant-tabs-bar { + margin: 0; + } + + .ant-list-item { + display: block; + } + + .collapse-title { + color: inherit; + font-weight: bold; + font-size: 18px; + padding: 10px 20px; + border-bottom: 2px solid; + } + + .collapse-title > i { + color: inherit; + font-size: 24px; + } +</style> +<body> +<a-layout id="app" v-cloak :class="themeSwitcher.currentTheme"> + {{ template "commonSider" . }} + <a-layout id="content-layout"> + <a-layout-content> + <a-spin :spinning="spinning" :delay="500" tip='{{ i18n "loading"}}'> + <a-space direction="vertical"> + <a-card hoverable style="margin-bottom: .5rem;"> + <a-row> + <a-col :xs="24" :sm="8" style="padding: 4px;"> + <a-space direction="horizontal"> + <a-button type="primary" :disabled="saveBtnDisable" @click="updateXraySetting">{{ i18n "pages.settings.save" }}</a-button> + <a-button type="danger" :disabled="!saveBtnDisable" @click="restartPanel">{{ i18n "pages.settings.restartPanel" }}</a-button> + </a-space> + </a-col> + <a-col :xs="24" :sm="16"> + <a-alert type="warning" style="float: right; width: fit-content" + message='{{ i18n "pages.settings.infoDesc" }}' + show-icon + > + </a-col> + </a-row> + </a-card> + <a-tabs class="ant-card-dark-box-nohover" default-active-key="tpl-1" :class="themeSwitcher.currentTheme" style="padding: 20px 20px;"> + <a-tab-pane key="tpl-1" tab='{{ i18n "pages.settings.templates.basicTemplate"}}' style="padding-top: 20px;"> + <a-space direction="horizontal" style="padding: 20px 20px"> + <a-button type="primary" @click="resetXrayConfigToDefault">{{ i18n "pages.settings.resetDefaultConfig" }}</a-button> + </a-space> + <a-collapse> + <a-collapse-panel header='{{ i18n "pages.settings.templates.generalConfigs"}}'> + <a-row :xs="24" :sm="24" :lg="12"> + <h2 class="collapse-title"> + <a-icon type="warning"></a-icon> + {{ i18n "pages.settings.templates.generalConfigsDesc" }} + </h2> + </a-row> + <a-list-item> + <a-row style="padding: 20px"> + <a-col :lg="24" :xl="12"> + <a-list-item-meta + title='{{ i18n "pages.settings.templates.xrayConfigFreedomStrategy" }}' + description='{{ i18n "pages.settings.templates.xrayConfigFreedomStrategyDesc" }}'/> + </a-col> + <a-col :lg="24" :xl="12"> + <template> + <a-select + v-model="freedomStrategy" + :dropdown-class-name="themeSwitcher.currentTheme" + style="width: 100%"> + <a-select-option v-for="s in outboundDomainStrategies" :value="s">[[ s ]]</a-select-option> + </a-select> + </template> + </a-col> + </a-row> + </a-list-item> + <a-row style="padding: 20px"> + <a-col :lg="24" :xl="12"> + <a-list-item-meta + title='{{ i18n "pages.settings.templates.xrayConfigRoutingStrategy" }}' + description='{{ i18n "pages.settings.templates.xrayConfigRoutingStrategyDesc" }}'/> + </a-col> + <a-col :lg="24" :xl="12"> + <template> + <a-select + v-model="routingStrategy" + :dropdown-class-name="themeSwitcher.currentTheme" + style="width: 100%"> + <a-select-option v-for="s in routingDomainStrategies" :value="s">[[ s ]]</a-select-option> + </a-select> + </template> + </a-col> + </a-row> + </a-list-item> + </a-collapse-panel> + <a-collapse-panel header='{{ i18n "pages.settings.templates.blockConfigs"}}'> + <a-row :xs="24" :sm="24" :lg="12"> + <h2 class="collapse-title"> + <a-icon type="warning"></a-icon> + {{ i18n "pages.settings.templates.blockConfigsDesc" }} + </h2> + </a-row> + <setting-list-item type="switch" title='{{ i18n "pages.settings.templates.xrayConfigTorrent"}}' desc='{{ i18n "pages.settings.templates.xrayConfigTorrentDesc"}}' v-model="torrentSettings"></setting-list-item> + <setting-list-item type="switch" title='{{ i18n "pages.settings.templates.xrayConfigPrivateIp"}}' desc='{{ i18n "pages.settings.templates.xrayConfigPrivateIpDesc"}}' v-model="privateIpSettings"></setting-list-item> + <setting-list-item type="switch" title='{{ i18n "pages.settings.templates.xrayConfigAds"}}' desc='{{ i18n "pages.settings.templates.xrayConfigAdsDesc"}}' v-model="AdsSettings"></setting-list-item> + <setting-list-item type="switch" title='{{ i18n "pages.settings.templates.xrayConfigFamily"}}' desc='{{ i18n "pages.settings.templates.xrayConfigFamilyDesc"}}' v-model="familyProtectSettings"></setting-list-item> + <setting-list-item type="switch" title='{{ i18n "pages.settings.templates.xrayConfigSpeedtest"}}' desc='{{ i18n "pages.settings.templates.xrayConfigSpeedtestDesc"}}' v-model="SpeedTestSettings"></setting-list-item> + </a-collapse-panel> + <a-collapse-panel header='{{ i18n "pages.settings.templates.blockCountryConfigs"}}'> + <a-row :xs="24" :sm="24" :lg="12"> + <h2 class="collapse-title"> + <a-icon type="warning"></a-icon> + {{ i18n "pages.settings.templates.blockCountryConfigsDesc" }} + </h2> + </a-row> + <setting-list-item type="switch" title='{{ i18n "pages.settings.templates.xrayConfigIRIp"}}' desc='{{ i18n "pages.settings.templates.xrayConfigIRIpDesc"}}' v-model="IRIpSettings"></setting-list-item> + <setting-list-item type="switch" title='{{ i18n "pages.settings.templates.xrayConfigIRDomain"}}' desc='{{ i18n "pages.settings.templates.xrayConfigIRDomainDesc"}}' v-model="IRDomainSettings"></setting-list-item> + <setting-list-item type="switch" title='{{ i18n "pages.settings.templates.xrayConfigChinaIp"}}' desc='{{ i18n "pages.settings.templates.xrayConfigChinaIpDesc"}}' v-model="ChinaIpSettings"></setting-list-item> + <setting-list-item type="switch" title='{{ i18n "pages.settings.templates.xrayConfigChinaDomain"}}' desc='{{ i18n "pages.settings.templates.xrayConfigChinaDomainDesc"}}' v-model="ChinaDomainSettings"></setting-list-item> + <setting-list-item type="switch" title='{{ i18n "pages.settings.templates.xrayConfigRussiaIp"}}' desc='{{ i18n "pages.settings.templates.xrayConfigRussiaIpDesc"}}' v-model="RussiaIpSettings"></setting-list-item> + <setting-list-item type="switch" title='{{ i18n "pages.settings.templates.xrayConfigRussiaDomain"}}' desc='{{ i18n "pages.settings.templates.xrayConfigRussiaDomainDesc"}}' v-model="RussiaDomainSettings"></setting-list-item> + </a-collapse-panel> + <a-collapse-panel header='{{ i18n "pages.settings.templates.directCountryConfigs"}}'> + <a-row :xs="24" :sm="24" :lg="12"> + <h2 class="collapse-title"> + <a-icon type="warning"></a-icon> + {{ i18n "pages.settings.templates.directCountryConfigsDesc" }} + </h2> + </a-row> + <setting-list-item type="switch" title='{{ i18n "pages.settings.templates.xrayConfigDirectIRIp"}}' desc='{{ i18n "pages.settings.templates.xrayConfigDirectIRIpDesc"}}' v-model="IRIpDirectSettings"></setting-list-item> + <setting-list-item type="switch" title='{{ i18n "pages.settings.templates.xrayConfigDirectIRDomain"}}' desc='{{ i18n "pages.settings.templates.xrayConfigDirectIRDomainDesc"}}' v-model="IRDomainDirectSettings"></setting-list-item> + <setting-list-item type="switch" title='{{ i18n "pages.settings.templates.xrayConfigDirectChinaIp"}}' desc='{{ i18n "pages.settings.templates.xrayConfigDirectChinaIpDesc"}}' v-model="ChinaIpDirectSettings"></setting-list-item> + <setting-list-item type="switch" title='{{ i18n "pages.settings.templates.xrayConfigDirectChinaDomain"}}' desc='{{ i18n "pages.settings.templates.xrayConfigDirectChinaDomainDesc"}}' v-model="ChinaDomainDirectSettings"></setting-list-item> + <setting-list-item type="switch" title='{{ i18n "pages.settings.templates.xrayConfigDirectRussiaIp"}}' desc='{{ i18n "pages.settings.templates.xrayConfigDirectRussiaIpDesc"}}' v-model="RussiaIpDirectSettings"></setting-list-item> + <setting-list-item type="switch" title='{{ i18n "pages.settings.templates.xrayConfigDirectRussiaDomain"}}' desc='{{ i18n "pages.settings.templates.xrayConfigDirectRussiaDomainDesc"}}' v-model="RussiaDomainDirectSettings"></setting-list-item> + </a-collapse-panel> + <a-collapse-panel header='{{ i18n "pages.settings.templates.ipv4Configs"}}'> + <a-row :xs="24" :sm="24" :lg="12"> + <h2 class="collapse-title"> + <a-icon type="warning"></a-icon> + {{ i18n "pages.settings.templates.ipv4ConfigsDesc" }} + </h2> + </a-row> + <setting-list-item type="switch" title='{{ i18n "pages.settings.templates.xrayConfigGoogleIPv4"}}' desc='{{ i18n "pages.settings.templates.xrayConfigGoogleIPv4Desc"}}' v-model="GoogleIPv4Settings"></setting-list-item> + <setting-list-item type="switch" title='{{ i18n "pages.settings.templates.xrayConfigNetflixIPv4"}}' desc='{{ i18n "pages.settings.templates.xrayConfigNetflixIPv4Desc"}}' v-model="NetflixIPv4Settings"></setting-list-item> + </a-collapse-panel> + <a-collapse-panel header='{{ i18n "pages.settings.templates.warpConfigs"}}'> + <a-row :xs="24" :sm="24" :lg="12"> + <h2 class="collapse-title"> + <a-icon type="warning"></a-icon> + {{ i18n "pages.settings.templates.warpConfigsDesc" }} + </h2> + </a-row> + <setting-list-item type="switch" title='{{ i18n "pages.settings.templates.xrayConfigGoogleWARP"}}' desc='{{ i18n "pages.settings.templates.xrayConfigGoogleWARPDesc"}}' v-model="GoogleWARPSettings"></setting-list-item> + <setting-list-item type="switch" title='{{ i18n "pages.settings.templates.xrayConfigOpenAIWARP"}}' desc='{{ i18n "pages.settings.templates.xrayConfigOpenAIWARPDesc"}}' v-model="OpenAIWARPSettings"></setting-list-item> + <setting-list-item type="switch" title='{{ i18n "pages.settings.templates.xrayConfigNetflixWARP"}}' desc='{{ i18n "pages.settings.templates.xrayConfigNetflixWARPDesc"}}' v-model="NetflixWARPSettings"></setting-list-item> + <setting-list-item type="switch" title='{{ i18n "pages.settings.templates.xrayConfigSpotifyWARP"}}' desc='{{ i18n "pages.settings.templates.xrayConfigSpotifyWARPDesc"}}' v-model="SpotifyWARPSettings"></setting-list-item> + </a-collapse-panel> + </a-collapse> + </a-tab-pane> + <a-tab-pane key="tpl-2" tab='{{ i18n "pages.settings.templates.manualLists"}}' style="padding-top: 20px;"> + <a-row :xs="24" :sm="24" :lg="12"> + <h2 class="collapse-title"> + <a-icon type="warning"></a-icon> + {{ i18n "pages.settings.templates.manualListsDesc" }} + </h2> + </a-row> + <a-collapse> + <a-collapse-panel header='{{ i18n "pages.settings.templates.manualBlockedIPs"}}'> + <setting-list-item type="textarea" v-model="manualBlockedIPs"></setting-list-item> + </a-collapse-panel> + <a-collapse-panel header='{{ i18n "pages.settings.templates.manualBlockedDomains"}}'> + <setting-list-item type="textarea" v-model="manualBlockedDomains"></setting-list-item> + </a-collapse-panel> + <a-collapse-panel header='{{ i18n "pages.settings.templates.manualDirectIPs"}}'> + <setting-list-item type="textarea" v-model="manualDirectIPs"></setting-list-item> + </a-collapse-panel> + <a-collapse-panel header='{{ i18n "pages.settings.templates.manualDirectDomains"}}'> + <setting-list-item type="textarea" v-model="manualDirectDomains"></setting-list-item> + </a-collapse-panel> + <a-collapse-panel header='{{ i18n "pages.settings.templates.manualIPv4Domains"}}'> + <setting-list-item type="textarea" v-model="manualIPv4Domains"></setting-list-item> + </a-collapse-panel> + <a-collapse-panel header='{{ i18n "pages.settings.templates.manualWARPDomains"}}'> + <setting-list-item type="textarea" v-model="manualWARPDomains"></setting-list-item> + </a-collapse-panel> + </a-collapse> + </a-tab-pane> + <a-tab-pane key="tpl-3" tab='{{ i18n "pages.settings.templates.advancedTemplate"}}' style="padding-top: 20px;"> + <a-collapse> + <a-collapse-panel header='{{ i18n "pages.settings.templates.xrayConfigInbounds"}}'> + <setting-list-item type="textarea" title='{{ i18n "pages.settings.templates.xrayConfigInbounds"}}' desc='{{ i18n "pages.settings.templates.xrayConfigInboundsDesc"}}' v-model="inboundSettings"></setting-list-item> + </a-collapse-panel> + <a-collapse-panel header='{{ i18n "pages.settings.templates.xrayConfigOutbounds"}}'> + <setting-list-item type="textarea" title='{{ i18n "pages.settings.templates.xrayConfigOutbounds"}}' desc='{{ i18n "pages.settings.templates.xrayConfigOutboundsDesc"}}' v-model="outboundSettings"></setting-list-item> + </a-collapse-panel> + <a-collapse-panel header='{{ i18n "pages.settings.templates.xrayConfigRoutings"}}'> + <setting-list-item type="textarea" title='{{ i18n "pages.settings.templates.xrayConfigRoutings"}}' desc='{{ i18n "pages.settings.templates.xrayConfigRoutingsDesc"}}' v-model="routingRuleSettings"></setting-list-item> + </a-collapse-panel> + </a-collapse> + </a-tab-pane> + <a-tab-pane key="tpl-4" tab='{{ i18n "pages.settings.templates.completeTemplate"}}' style="padding-top: 20px;"> + <setting-list-item type="textarea" title='{{ i18n "pages.settings.templates.xrayConfigTemplate"}}' desc='{{ i18n "pages.settings.templates.xrayConfigTemplateDesc"}}' v-model="this.xraySetting"></setting-list-item> + </a-tab-pane> + </a-tabs> + </a-space> + </a-spin> + </a-layout-content> + </a-layout> +</a-layout> +{{template "js" .}} +{{template "component/themeSwitcher" .}} +{{template "component/setting"}} +<script> + const app = new Vue({ + delimiters: ['[[', ']]'], + el: '#app', + data: { + siderDrawer, + themeSwitcher, + spinning: false, + oldXraySetting: '', + xraySetting: '', + saveBtnDisable: true, + ipv4Settings: { + tag: "IPv4", + protocol: "freedom", + settings: { + domainStrategy: "UseIPv4" + } + }, + warpSettings: { + tag: "WARP", + protocol: "socks", + settings: { + servers: [ + { + address: "127.0.0.1", + port: 40000 + } + ] + } + }, + directSettings: { + tag: "direct", + protocol: "freedom" + }, + outboundDomainStrategies: ["AsIs", "UseIP", "UseIPv4", "UseIPv6"], + routingDomainStrategies: ["AsIs", "IPIfNonMatch", "IPOnDemand"], + settingsData: { + protocols: { + bittorrent: ["bittorrent"], + }, + ips: { + local: ["geoip:private"], + cn: ["geoip:cn"], + ir: ["ext:geoip_IR.dat:ir","ext:geoip_IR.dat:arvancloud","ext:geoip_IR.dat:derakcloud","ext:geoip_IR.dat:iranserver"], + ru: ["geoip:ru"], + }, + domains: { + ads: [ + "geosite:category-ads-all", + "ext:geosite_IR.dat:category-ads-all" + ], + speedtest: ["geosite:speedtest"], + openai: ["geosite:openai"], + google: ["geosite:google"], + spotify: ["geosite:spotify"], + netflix: ["geosite:netflix"], + cn: [ + "geosite:cn", + "regexp:.*\\.cn$" + ], + ru: [ + "geosite:category-gov-ru", + "regexp:.*\\.ru$" + ], + ir: [ + "regexp:.*\\.ir$", + "regexp:.*\\.xn--mgba3a4f16a$", // .ایران + "ext:geosite_IR.dat:ir" // have rules to bypass all .ir domains. + ] + }, + familyProtectDNS: { + "servers": [ + "1.1.1.3", // https://developers.cloudflare.com/1.1.1.1/setup/ + "1.0.0.3", + "94.140.14.15", // https://adguard-dns.io/kb/general/dns-providers/ + "94.140.15.16" + ], + "queryStrategy": "UseIPv4" + }, + } + }, + methods: { + loading(spinning = true) { + this.spinning = spinning; + }, + async getXraySetting() { + this.loading(true); + const msg = await HttpUtil.post("/panel/xray/"); + this.loading(false); + if (msg.success) { + this.oldXraySetting = msg.obj; + this.xraySetting = msg.obj; + this.saveBtnDisable = true; + } + }, + async updateXraySetting() { + this.loading(true); + const msg = await HttpUtil.post("/panel/xray/update", {xraySetting : this.xraySetting}); + this.loading(false); + if (msg.success) { + await this.getXraySetting(); + } + }, + async restartPanel() { + await new Promise(resolve => { + this.$confirm({ + title: '{{ i18n "pages.settings.restartPanel" }}', + content: '{{ i18n "pages.settings.restartPanelDesc" }}', + class: themeSwitcher.currentTheme, + okText: '{{ i18n "sure" }}', + cancelText: '{{ i18n "cancel" }}', + onOk: () => resolve(), + }); + }); + this.loading(true); + const msg = await HttpUtil.post("/panel/setting/restartPanel"); + this.loading(false); + if (msg.success) { + this.loading(true); + await PromiseUtil.sleep(5000); + var { webCertFile, webKeyFile, webDomain: host, webPort: port, webBasePath: base } = this.xraySetting; + if (host == this.oldXraySetting.webDomain) host = null; + if (port == this.oldXraySetting.webPort) port = null; + const isTLS = webCertFile !== "" || webKeyFile !== ""; + const url = buildURL({ host, port, isTLS, base, path: "panel/settings" }); + window.location.replace(url); + } + }, + async fetchUserSecret() { + this.loading(true); + const userMessage = await HttpUtil.post("/panel/setting/getUserSecret", this.user); + if (userMessage.success) { + this.user = userMessage.obj; + } + this.loading(false); + }, + async updateSecret() { + this.loading(true); + const msg = await HttpUtil.post("/panel/setting/updateUserSecret", this.user); + if (msg.success) { + this.user = msg.obj; + window.location.replace(basePath + "logout"); + } + this.loading(false); + await this.updateXraySetting(); + }, + generateRandomString(length) { + var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; + let randomString = ""; + for (let i = 0; i < length; i++) { + randomString += chars[Math.floor(Math.random() * chars.length)]; + } + return randomString; + }, + async getNewSecret() { + this.loading(true); + await PromiseUtil.sleep(600); + const newSecret = this.generateRandomString(64); + this.user.loginSecret = newSecret; + document.getElementById("token").textContent = newSecret; + this.loading(false); + }, + async toggleToken(value) { + if (value) { + await this.getNewSecret(); + } else { + this.user.loginSecret = ""; + } + }, + async resetXrayConfigToDefault() { + this.loading(true); + const msg = await HttpUtil.get("/panel/setting/getDefaultJsonConfig"); + this.loading(false); + if (msg.success) { + this.templateSettings = JSON.parse(JSON.stringify(msg.obj, null, 2)); + this.saveBtnDisable = true; + } + }, + syncRulesWithOutbound(tag, setting) { + const newTemplateSettings = {...this.templateSettings}; + const haveRules = newTemplateSettings.routing.rules.some((r) => r?.outboundTag === tag); + const outboundIndex = newTemplateSettings.outbounds.findIndex((o) => o.tag === tag); + if (!haveRules && outboundIndex >= 0) { + newTemplateSettings.outbounds.splice(outboundIndex, 1); + } + if (haveRules && outboundIndex === -1) { + newTemplateSettings.outbounds.push(setting); + } + this.templateSettings = newTemplateSettings; + }, + templateRuleGetter(routeSettings) { + const { property, outboundTag } = routeSettings; + let result = []; + if (this.templateSettings != null) { + this.templateSettings.routing.rules.forEach( + (routingRule) => { + if ( + routingRule.hasOwnProperty(property) && + routingRule.hasOwnProperty("outboundTag") && + routingRule.outboundTag === outboundTag + ) { + result.push(...routingRule[property]); + } + } + ); + } + return result; + }, + templateRuleSetter(routeSettings) { + const { data, property, outboundTag } = routeSettings; + const oldTemplateSettings = this.templateSettings; + const newTemplateSettings = oldTemplateSettings; + currentProperty = this.templateRuleGetter({ outboundTag, property }) + if (currentProperty.length == 0) { + const propertyRule = { + type: "field", + outboundTag, + [property]: data + }; + newTemplateSettings.routing.rules.push(propertyRule); + } + else { + const newRules = []; + insertedOnce = false; + newTemplateSettings.routing.rules.forEach( + (routingRule) => { + if ( + routingRule.hasOwnProperty(property) && + routingRule.hasOwnProperty("outboundTag") && + routingRule.outboundTag === outboundTag + ) { + if (!insertedOnce && data.length > 0) { + insertedOnce = true; + routingRule[property] = data; + newRules.push(routingRule); + } + } + else { + newRules.push(routingRule); + } + } + ); + newTemplateSettings.routing.rules = newRules; + } + this.templateSettings = newTemplateSettings; + } + }, + async mounted() { + await this.getXraySetting(); + while (true) { + await PromiseUtil.sleep(600); + this.saveBtnDisable = this.oldXraySetting === this.xraySetting; + } + }, + computed: { + templateSettings: { + get: function () { return this.xraySetting ? JSON.parse(this.xraySetting) : null; }, + set: function (newValue) { this.xraySetting = JSON.stringify(newValue, null, 2); }, + }, + inboundSettings: { + get: function () { return this.templateSettings ? JSON.stringify(this.templateSettings.inbounds, null, 2) : null; }, + set: function (newValue) { + newTemplateSettings = this.templateSettings; + newTemplateSettings.inbounds = JSON.parse(newValue); + this.templateSettings = newTemplateSettings; + }, + }, + outboundSettings: { + get: function () { return this.templateSettings ? JSON.stringify(this.templateSettings.outbounds, null, 2) : null; }, + set: function (newValue) { + newTemplateSettings = this.templateSettings; + newTemplateSettings.outbounds = JSON.parse(newValue); + this.templateSettings = newTemplateSettings; + }, + }, + routingRuleSettings: { + get: function () { return this.templateSettings ? JSON.stringify(this.templateSettings.routing.rules, null, 2) : null; }, + set: function (newValue) { + newTemplateSettings = this.templateSettings; + newTemplateSettings.routing.rules = JSON.parse(newValue); + this.templateSettings = newTemplateSettings; + }, + }, + freedomStrategy: { + get: function () { + if (!this.templateSettings) return "AsIs"; + freedomOutbound = this.templateSettings.outbounds.find((o) => o.protocol === "freedom" && !o.tag); + if (!freedomOutbound) return "AsIs"; + if (!freedomOutbound.settings || !freedomOutbound.settings.domainStrategy) return "AsIs"; + return freedomOutbound.settings.domainStrategy; + }, + set: function (newValue) { + newTemplateSettings = this.templateSettings; + freedomOutboundIndex = newTemplateSettings.outbounds.findIndex((o) => o.protocol === "freedom" && !o.tag); + if (!newTemplateSettings.outbounds[freedomOutboundIndex].settings) { + newTemplateSettings.outbounds[freedomOutboundIndex].settings = {"domainStrategy": newValue}; + } else { + newTemplateSettings.outbounds[freedomOutboundIndex].settings.domainStrategy = newValue; + } + this.templateSettings = newTemplateSettings; + } + }, + routingStrategy: { + get: function () { + if (!this.templateSettings || !this.templateSettings.routing || !this.templateSettings.routing.domainStrategy) return "AsIs"; + return this.templateSettings.routing.domainStrategy; + }, + set: function (newValue) { + newTemplateSettings = this.templateSettings; + newTemplateSettings.routing.domainStrategy = newValue; + this.templateSettings = newTemplateSettings; + } + }, + blockedIPs: { + get: function () { + return this.templateRuleGetter({ outboundTag: "blocked", property: "ip" }); + }, + set: function (newValue) { + this.templateRuleSetter({ outboundTag: "blocked", property: "ip", data: newValue }); + } + }, + blockedDomains: { + get: function () { + return this.templateRuleGetter({ outboundTag: "blocked", property: "domain" }); + }, + set: function (newValue) { + this.templateRuleSetter({ outboundTag: "blocked", property: "domain", data: newValue }); + } + }, + blockedProtocols: { + get: function () { + return this.templateRuleGetter({ outboundTag: "blocked", property: "protocol" }); + }, + set: function (newValue) { + this.templateRuleSetter({ outboundTag: "blocked", property: "protocol", data: newValue }); + } + }, + directIPs: { + get: function () { + return this.templateRuleGetter({ outboundTag: "direct", property: "ip" }); + }, + set: function (newValue) { + this.templateRuleSetter({ outboundTag: "direct", property: "ip", data: newValue }); + this.syncRulesWithOutbound("direct", this.directSettings); + } + }, + directDomains: { + get: function () { + return this.templateRuleGetter({ outboundTag: "direct", property: "domain" }); + }, + set: function (newValue) { + this.templateRuleSetter({ outboundTag: "direct", property: "domain", data: newValue }); + this.syncRulesWithOutbound("direct", this.directSettings); + } + }, + ipv4Domains: { + get: function () { + return this.templateRuleGetter({ outboundTag: "IPv4", property: "domain" }); + }, + set: function (newValue) { + this.templateRuleSetter({ outboundTag: "IPv4", property: "domain", data: newValue }); + this.syncRulesWithOutbound("IPv4", this.ipv4Settings); + } + }, + warpDomains: { + get: function () { + return this.templateRuleGetter({ outboundTag: "WARP", property: "domain" }); + }, + set: function (newValue) { + this.templateRuleSetter({ outboundTag: "WARP", property: "domain", data: newValue }); + this.syncRulesWithOutbound("WARP", this.warpSettings); + } + }, + manualBlockedIPs: { + get: function () { return JSON.stringify(this.blockedIPs, null, 2); }, + set: debounce(function (value) { this.blockedIPs = JSON.parse(value); }, 1000) + }, + manualBlockedDomains: { + get: function () { return JSON.stringify(this.blockedDomains, null, 2); }, + set: debounce(function (value) { this.blockedDomains = JSON.parse(value); }, 1000) + }, + manualDirectIPs: { + get: function () { return JSON.stringify(this.directIPs, null, 2); }, + set: debounce(function (value) { this.directIPs = JSON.parse(value); }, 1000) + }, + manualDirectDomains: { + get: function () { return JSON.stringify(this.directDomains, null, 2); }, + set: debounce(function (value) { this.directDomains = JSON.parse(value); }, 1000) + }, + manualIPv4Domains: { + get: function () { return JSON.stringify(this.ipv4Domains, null, 2); }, + set: debounce(function (value) { this.ipv4Domains = JSON.parse(value); }, 1000) + }, + manualWARPDomains: { + get: function () { return JSON.stringify(this.warpDomains, null, 2); }, + set: debounce(function (value) { this.warpDomains = JSON.parse(value); }, 1000) + }, + torrentSettings: { + get: function () { + return doAllItemsExist(this.settingsData.protocols.bittorrent, this.blockedProtocols); + }, + set: function (newValue) { + if (newValue) { + this.blockedProtocols = [...this.blockedProtocols, ...this.settingsData.protocols.bittorrent]; + } else { + this.blockedProtocols = this.blockedProtocols.filter(data => !this.settingsData.protocols.bittorrent.includes(data)); + } + }, + }, + privateIpSettings: { + get: function () { + return doAllItemsExist(this.settingsData.ips.local, this.blockedIPs); + }, + set: function (newValue) { + if (newValue) { + this.blockedIPs = [...this.blockedIPs, ...this.settingsData.ips.local]; + } else { + this.blockedIPs = this.blockedIPs.filter(data => !this.settingsData.ips.local.includes(data)); + } + }, + }, + AdsSettings: { + get: function () { + return doAllItemsExist(this.settingsData.domains.ads, this.blockedDomains); + }, + set: function (newValue) { + if (newValue) { + this.blockedDomains = [...this.blockedDomains, ...this.settingsData.domains.ads]; + } else { + this.blockedDomains = this.blockedDomains.filter(data => !this.settingsData.domains.ads.includes(data)); + } + }, + }, + SpeedTestSettings: { + get: function () { + return doAllItemsExist(this.settingsData.domains.speedtest, this.blockedDomains); + }, + set: function (newValue) { + if (newValue) { + this.blockedDomains = [...this.blockedDomains, ...this.settingsData.domains.speedtest]; + } else { + this.blockedDomains = this.blockedDomains.filter(data => !this.settingsData.domains.speedtest.includes(data)); + } + }, + }, + familyProtectSettings: { + get: function () { + if (!this.templateSettings || !this.templateSettings.dns || !this.templateSettings.dns.servers) return false; + return doAllItemsExist(this.templateSettings.dns.servers, this.settingsData.familyProtectDNS.servers); + }, + set: function (newValue) { + newTemplateSettings = this.templateSettings; + if (newValue) { + newTemplateSettings.dns = this.settingsData.familyProtectDNS; + } else { + delete newTemplateSettings.dns; + } + this.templateSettings = newTemplateSettings; + }, + }, + GoogleIPv4Settings: { + get: function () { + return doAllItemsExist(this.settingsData.domains.google, this.ipv4Domains); + }, + set: function (newValue) { + if (newValue) { + this.ipv4Domains = [...this.ipv4Domains, ...this.settingsData.domains.google]; + } else { + this.ipv4Domains = this.ipv4Domains.filter(data => !this.settingsData.domains.google.includes(data)); + } + }, + }, + NetflixIPv4Settings: { + get: function () { + return doAllItemsExist(this.settingsData.domains.netflix, this.ipv4Domains); + }, + set: function (newValue) { + if (newValue) { + this.ipv4Domains = [...this.ipv4Domains, ...this.setting
|
