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
path: root/web
diff options
context:
space:
mode:
authorMHSanaei <ho3ein.sanaei@gmail.com>2023-05-16 23:09:59 +0300
committerMHSanaei <ho3ein.sanaei@gmail.com>2023-05-16 23:09:59 +0300
commit837d7f77a16bf570735fb6d5bb5e3073e03d8f43 (patch)
treefea08a9e264976bf4fc6828ae3bd0d1bf0e7d5f4 /web
parentd0213ce50b453933e635cf6df32aecf3f16d6fdc (diff)
update - xray configuration
Co-Authored-By: Alireza Ahmadi <alireza7@gmail.com>
Diffstat (limited to 'web')
-rw-r--r--web/assets/js/util/common.js9
-rw-r--r--web/html/xui/settings.html699
-rw-r--r--web/translation/translate.en_US.toml103
-rw-r--r--web/translation/translate.fa_IR.toml109
-rw-r--r--web/translation/translate.ru_RU.toml161
-rw-r--r--web/translation/translate.zh_Hans.toml95
6 files changed, 756 insertions, 420 deletions
diff --git a/web/assets/js/util/common.js b/web/assets/js/util/common.js
index 808b1ba9..a695f081 100644
--- a/web/assets/js/util/common.js
+++ b/web/assets/js/util/common.js
@@ -90,3 +90,12 @@ function setCookie(cname, cvalue, exdays) {
let expires = 'expires=' + d.toUTCString();
document.cookie = cname + '=' + cvalue + ';' + expires + ';path=/';
}
+
+function doAllItemsExist(array1, array2) {
+ for (let i = 0; i < array1.length; i++) {
+ if (!array2.includes(array1[i])) {
+ return false;
+ }
+ }
+ return true;
+} \ No newline at end of file
diff --git a/web/html/xui/settings.html b/web/html/xui/settings.html
index 49e62df9..7226c0ac 100644
--- a/web/html/xui/settings.html
+++ b/web/html/xui/settings.html
@@ -24,7 +24,6 @@
background: white;
}
</style>
-
<body>
<a-layout id="app" v-cloak>
{{ template "commonSider" . }}
@@ -64,7 +63,8 @@
style="width: 100%"
>
<a-select-option :value="l.value" :label="l.value" v-for="l in supportLangs">
- <span role="img" aria-label="l.name" v-text="l.icon"></span>&nbsp;&nbsp;<span v-text="l.name"></span>
+ <span role="img" aria-label="l.name" v-text="l.icon"></span>
+ &nbsp;&nbsp;<span v-text="l.name"></span>
</a-select-option>
</a-select>
</template>
@@ -72,8 +72,13 @@
</a-row>
</a-list-item>
</a-list>
+ <a-row :xs="24" :sm="24" :lg="12">
+ <h2 style="color: inherit; font-weight: bold; font-size: 16px; padding: 5px 5px; text-align: center;">
+ <a-icon type="warning" style="color: inherit; font-size: 24px;"></a-icon>
+ {{ i18n "pages.settings.infoDesc" }}
+ </h2>
+ </a-row>
</a-tab-pane>
-
<a-tab-pane key="2" tab='{{ i18n "pages.settings.securitySettings"}}' style="padding: 20px;">
<a-tabs class="ant-card-dark-securitybox-nohover" default-active-key="sec-1" :class="themeSwitcher.darkCardClass">
<a-tab-pane key="sec-1" tab='{{ i18n "pages.settings.security.admin"}}'>
@@ -116,7 +121,7 @@
</a-col>
<a-col :lg="24" :xl="12">
<svg
- @click="getNewSecret"
+ @click="generateRandomString"
xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="anticon anticon-question-circle" viewBox="0 0 16 16"><path d="M11.534 7h3.932a.25.25 0 0 1 .192.41l-1.966 2.36a.25.25 0 0 1-.384 0l-1.966-2.36a.25.25 0 0 1 .192-.41zm-11 2h3.932a.25.25 0 0 0 .192-.41L2.692 6.23a.25.25 0 0 0-.384 0L.342 8.59A.25.25 0 0 0 .534 9z"/><path fill-rule="evenodd" d="M8 3c-1.552 0-2.94.707-3.857 1.818a.5.5 0 1 1-.771-.636A6.002 6.002 0 0 1 13.917 7H12.9A5.002 5.002 0 0 0 8 3zM3.1 9a5.002 5.002 0 0 0 8.757 2.182.5.5 0 1 1 .771.636A6.002 6.002 0 0 1 2.083 9H3.1z"/>
</svg>
<template>
@@ -138,7 +143,12 @@
<a-button type="primary" @click="resetXrayConfigToDefault">{{ i18n "pages.settings.resetDefaultConfig" }}</a-button>
</a-space>
<a-divider style="padding: 20px;">{{ i18n "pages.settings.templates.title"}} </a-divider>
-
+ <a-row :xs="24" :sm="24" :lg="12">
+ <h2 style="color: inherit; font-weight: bold; font-size: 16px; padding: 5px 5px; text-align: center;">
+ <a-icon type="warning" style="color: inherit; font-size: 24px;"></a-icon>
+ {{ i18n "pages.settings.infoDesc" }}
+ </h2>
+ </a-row>
<a-tabs class="ant-card-dark-box-nohover" default-active-key="tpl-1" :class="themeSwitcher.darkCardClass" style="padding: 20px 20px;">
<a-tab-pane key="tpl-1" tab='{{ i18n "pages.settings.templates.basicTemplate"}}' style="padding-top: 20px;">
<a-collapse>
@@ -149,17 +159,62 @@
{{ 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.darkCardClass"
+ 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.darkCardClass"
+ 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 style="color: inherit; font-weight: bold; font-size: 18px; padding: 10px 20px; border-bottom: 2px solid;">
+ <a-icon type="warning" style="color: inherit; font-size: 24px;"></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.xrayConfigPorn"}}' desc='{{ i18n "pages.settings.templates.xrayConfigPornDesc"}}' v-model="PornSettings"></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.countryConfigs"}}'>
+ <a-collapse-panel header='{{ i18n "pages.settings.templates.blockCountryConfigs"}}'>
<a-row :xs="24" :sm="24" :lg="12">
<h2 style="color: inherit; font-weight: bold; font-size: 18px; padding: 10px 20px; border-bottom: 2px solid;">
<a-icon type="warning" style="color: inherit; font-size: 24px;"></a-icon>
- {{ i18n "pages.settings.templates.countryConfigsDesc" }}
+ {{ 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>
@@ -169,6 +224,20 @@
<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 style="color: inherit; font-weight: bold; font-size: 18px; padding: 10px 20px; border-bottom: 2px solid;">
+ <a-icon type="warning" style="color: inherit; font-size: 24px;"></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 style="color: inherit; font-weight: bold; font-size: 18px; padding: 10px 20px; border-bottom: 2px solid;">
@@ -191,6 +260,18 @@
<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-panel header='{{ i18n "pages.settings.templates.manualLists"}}'>
+ <a-row :xs="24" :sm="24" :lg="12">
+ <h2 style="color: inherit; font-weight: bold; font-size: 18px; padding: 10px 20px; border-bottom: 2px solid;">
+ <a-icon type="warning" style="color: inherit; font-size: 24px;"></a-icon>
+ {{ i18n "pages.settings.templates.manualListsDesc" }}
+ </h2>
+ </a-row>
+ <setting-list-item type="textarea" title='{{ i18n "pages.settings.templates.manualBlockedIPs"}}' v-model="manualBlockedIPs"></setting-list-item>
+ <setting-list-item type="textarea" title='{{ i18n "pages.settings.templates.manualBlockedDomains"}}' v-model="manualBlockedDomains"></setting-list-item>
+ <setting-list-item type="textarea" title='{{ i18n "pages.settings.templates.manualDirectIPs"}}' v-model="manualDirectIPs"></setting-list-item>
+ <setting-list-item type="textarea" title='{{ i18n "pages.settings.templates.manualDirectDomains"}}' v-model="manualDirectDomains"></setting-list-item>
+ </a-collapse-panel>
</a-collapse>
</a-tab-pane>
<a-tab-pane key="tpl-2" tab='{{ i18n "pages.settings.templates.advancedTemplate"}}' style="padding-top: 20px;">
@@ -222,6 +303,12 @@
<setting-list-item type="switch" title='{{ i18n "pages.settings.tgNotifyBackup" }}' desc='{{ i18n "pages.settings.tgNotifyBackupDesc" }}' v-model="allSetting.tgBotBackup"></setting-list-item>
<setting-list-item type="number" title='{{ i18n "pages.settings.tgNotifyCpu" }}' desc='{{ i18n "pages.settings.tgNotifyCpuDesc" }}' v-model="allSetting.tgCpu" :min="0" :max="100"></setting-list-item>
</a-list>
+ <a-row :xs="24" :sm="24" :lg="12">
+ <h2 style="color: inherit; font-weight: bold; font-size: 16px; padding: 5px 5px; text-align: center;">
+ <a-icon type="warning" style="color: inherit; font-size: 24px;"></a-icon>
+ {{ i18n "pages.settings.infoDesc" }}
+ </h2>
+ </a-row>
</a-tab-pane>
</a-tabs>
</a-space>
@@ -229,14 +316,11 @@
</a-layout-content>
</a-layout>
</a-layout>
-
{{template "js" .}}
{{template "component/themeSwitcher" .}}
{{template "component/password" .}}
{{template "component/setting"}}
-
<script>
-
const app = new Vue({
delimiters: ['[[', ']]'],
el: '#app',
@@ -268,13 +352,18 @@
]
}
},
+ directSettings: {
+ tag: "direct",
+ protocol: "freedom"
+ },
+ outboundDomainStrategies: ["AsIs", "UseIP", "UseIPv4", "UseIPv6"],
+ routingDomainStrategies: ["AsIs", "IPIfNonMatch", "IPOnDemand"],
settingsData: {
protocols: {
bittorrent: ["bittorrent"],
},
ips: {
local: ["geoip:private"],
- google: ["geoip:google"],
cn: ["geoip:cn"],
ir: ["geoip:ir"],
ru: ["geoip:ru"],
@@ -284,9 +373,9 @@
"geosite:category-ads-all",
"geosite:category-ads",
"geosite:google-ads",
- "geosite:spotify-ads"
+ "geosite:spotify-ads",
+ "ext:iran.dat:ads"
],
- porn: ["geosite:category-porn"],
speedtest: ["geosite:speedtest"],
openai: ["geosite:openai"],
google: ["geosite:google"],
@@ -304,15 +393,23 @@
"regexp:.*\\.ir$",
"ext:iran.dat:ir",
"ext:iran.dat:other",
- "ext:iran.dat:ads",
"geosite:category-ir"
]
},
+ familyProtectDNS: {
+ "servers": [
+ "1.1.1.3", // https://developers.cloudflare.com/1.1.1.1/setup/
+ "1.0.0.3",
+ "94.140.14.14", // https://adguard-dns.io/kb/general/dns-providers/
+ "94.140.15.15"
+ ],
+ "queryStrategy": "UseIPv4"
+ },
}
},
methods: {
- loading(spinning = true, obj) {
- if (obj == null) this.spinning = spinning;
+ loading(spinning = true) {
+ this.spinning = spinning;
},
async getAllSetting() {
this.loading(true);
@@ -323,7 +420,7 @@
this.allSetting = new AllSetting(msg.obj);
this.saveBtnDisable = true;
}
- await this.getUserSecret();
+ await this.fetchUserSecret();
},
async updateAllSetting() {
this.loading(true);
@@ -361,10 +458,11 @@
window.location.replace(this.allSetting.webBasePath + "panel/settings");
}
},
- async getUserSecret() {
- const user_msg = await HttpUtil.post("/panel/setting/getUserSecret", this.user);
- if (user_msg.success) {
- this.user = user_msg.obj;
+ 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);
},
@@ -373,27 +471,33 @@
const msg = await HttpUtil.post("/panel/setting/updateUserSecret", this.user);
if (msg.success) {
this.user = msg.obj;
- window.location.replace(basePath + "logout")
+ window.location.replace(basePath + "logout");
}
this.loading(false);
await this.updateAllSetting();
},
- async getNewSecret() {
- this.loading(true);
- await PromiseUtil.sleep(1000);
+ generateRandomString(length) {
var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
- var string = "";
- var len = 64;
- for (var ii = 0; ii < len; ii++) {
- string += chars[Math.floor(Math.random() * chars.length)];
+ let randomString = "";
+ for (let i = 0; i < length; i++) {
+ randomString += chars[Math.floor(Math.random() * chars.length)];
}
- this.user.loginSecret = string;
- document.getElementById("token").value = this.user.loginSecret;
+ 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) this.getNewSecret();
- else this.user.loginSecret = "";
+ if (value) {
+ await this.getNewSecret();
+ } else {
+ this.user.loginSecret = "";
+ }
},
async resetXrayConfigToDefault() {
this.loading(true);
@@ -404,23 +508,21 @@
this.saveBtnDisable = true;
}
},
- checkRequiredOutbounds() {
- const newTemplateSettings = this.templateSettings;
- const haveIPv4Outbounds = newTemplateSettings.outbounds.some((o) => o?.tag === "IPv4");
- const haveIPv4Rules = newTemplateSettings.routing.rules.some((r) => r?.outboundTag === "IPv4");
- const haveWARPOutbounds = newTemplateSettings.outbounds.some((o) => o?.tag === "WARP");
- const haveWARPRules = newTemplateSettings.routing.rules.some((r) => r?.outboundTag === "WARP");
- if (haveWARPRules && !haveWARPOutbounds) {
- newTemplateSettings.outbounds.push(this.warpSettings);
+ 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 (haveIPv4Rules && !haveIPv4Outbounds) {
- newTemplateSettings.outbounds.push(this.ipv4Settings);
+ if (haveRules && outboundIndex === -1) {
+ newTemplateSettings.outbounds.push(setting);
}
this.templateSettings = newTemplateSettings;
},
templateRuleGetter(routeSettings) {
- const { data, property, outboundTag } = routeSettings;
- let result = false;
+ const { property, outboundTag } = routeSettings;
+ let result = [];
if (this.templateSettings != null) {
this.templateSettings.routing.rules.forEach(
(routingRule) => {
@@ -429,9 +531,7 @@
routingRule.hasOwnProperty("outboundTag") &&
routingRule.outboundTag === outboundTag
) {
- if (data.includes(routingRule[property][0])) {
- result = true;
- }
+ result.push(...routingRule[property]);
}
}
);
@@ -439,10 +539,11 @@
return result;
},
templateRuleSetter(routeSettings) {
- const { newValue, data, property, outboundTag } = routeSettings;
+ const { data, property, outboundTag } = routeSettings;
const oldTemplateSettings = this.templateSettings;
const newTemplateSettings = oldTemplateSettings;
- if (newValue) {
+ currentProperty = this.templateRuleGetter({ outboundTag, property })
+ if (currentProperty.length == 0) {
const propertyRule = {
type: "field",
outboundTag,
@@ -452,6 +553,7 @@
}
else {
const newRules = [];
+ insertedOnce = false;
newTemplateSettings.routing.rules.forEach(
(routingRule) => {
if (
@@ -459,23 +561,26 @@
routingRule.hasOwnProperty("outboundTag") &&
routingRule.outboundTag === outboundTag
) {
- if (data.includes(routingRule[property][0])) {
- return;
+ if (!insertedOnce && data.length > 0) {
+ insertedOnce = true;
+ routingRule[property] = data;
+ newRules.push(routingRule);
}
}
- newRules.push(routingRule);
+ else {
+ newRules.push(routingRule);
+ }
}
);
newTemplateSettings.routing.rules = newRules;
}
this.templateSettings = newTemplateSettings;
- this.checkRequiredOutbounds();
}
},
async mounted() {
await this.getAllSetting();
while (true) {
- await PromiseUtil.sleep(1000);
+ await PromiseUtil.sleep(600);
this.saveBtnDisable = this.oldAllSetting.equals(this.allSetting);
}
},
@@ -508,299 +613,417 @@
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);
+ }
+ },
+ 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)
+ },
torrentSettings: {
get: function () {
- return this.templateRuleGetter({
- outboundTag: "blocked",
- property: "protocol",
- data: this.settingsData.protocols.bittorrent
- });
+ return doAllItemsExist(this.settingsData.protocols.bittorrent, this.blockedProtocols);
},
set: function (newValue) {
- this.templateRuleSetter({
- newValue,
- outboundTag: "blocked",
- property: "protocol",
- data: this.settingsData.protocols.bittorrent
- });
+ 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 this.templateRuleGetter({
- outboundTag: "blocked",
- property: "ip",
- data: this.settingsData.ips.local
- });
+ return doAllItemsExist(this.settingsData.ips.local, this.blockedIPs);
},
set: function (newValue) {
- this.templateRuleSetter({
- newValue,
- outboundTag: "blocked",
- property: "ip",
- data: this.settingsData.ips.local
- });
+ 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 this.templateRuleGetter({
- outboundTag: "blocked",
- property: "domain",
- data: this.settingsData.domains.ads
- });
+ return doAllItemsExist(this.settingsData.domains.ads, this.blockedDomains);
},
set: function (newValue) {
- this.templateRuleSetter({
- newValue,
- outboundTag: "blocked",
- property: "domain",
- data: this.settingsData.domains.ads
- });
+ if (newValue) {
+ this.blockedDomains = [...this.blockedDomains, ...this.settingsData.domains.ads];
+ } else {
+ this.blockedDomains = this.blockedDomains.filter(data => !this.settingsData.domains.ads.includes(data));
+ }
},
},
- PornSettings: {
+ SpeedTestSettings: {
get: function () {
- return this.templateRuleGetter({
- outboundTag: "blocked",
- property: "domain",
- data: this.settingsData.domains.porn
- });
+ return doAllItemsExist(this.settingsData.domains.speedtest, this.blockedDomains);
},
set: function (newValue) {
- this.templateRuleSetter({
- newValue,
- outboundTag: "blocked",
- property: "domain",
- data: this.settingsData.domains.porn
- });
+ if (newValue) {
+ this.blockedDomains = [...this.blockedDomains, ...this.settingsData.domains.speedtest];
+ } else {
+ this.blockedDomains = this.blockedDomains.filter(data => !this.settingsData.domains.speedtest.includes(data));
+ }
},
},
- SpeedTestSettings: {
+ familyProtectSettings: {
get: function () {
- return this.templateRuleGetter({
- outboundTag: "blocked",
- property: "domain",
- data: this.settingsData.domains.speedtest
- });
+ 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) {
- this.templateRuleSetter({
- newValue,
- outboundTag: "blocked",
- property: "domain",
- data: this.settingsData.domains.speedtest
- });
+ newTemplateSettings = this.templateSettings;
+ if (newValue) {
+ newTemplateSettings.dns = this.settingsData.familyProtectDNS;
+ } else {
+ delete newTemplateSettings.dns;
+ }
+ this.templateSettings = newTemplateSettings;