mirror of
https://github.com/itdoginfo/podkop.git
synced 2025-12-06 03:26:51 +03:00
fix: run prettier for all js files
This commit is contained in:
@@ -1,22 +1,22 @@
|
||||
'use strict';
|
||||
'require baseclass';
|
||||
'require form';
|
||||
'require ui';
|
||||
'require uci';
|
||||
'require fs';
|
||||
'require view.podkop.main as main';
|
||||
"use strict";
|
||||
"require baseclass";
|
||||
"require form";
|
||||
"require ui";
|
||||
"require uci";
|
||||
"require fs";
|
||||
"require view.podkop.main as main";
|
||||
|
||||
function createDashboardContent(section) {
|
||||
const o = section.option(form.DummyValue, '_mount_node');
|
||||
o.rawhtml = true;
|
||||
o.cfgvalue = () => {
|
||||
main.DashboardTab.initController();
|
||||
return main.DashboardTab.render();
|
||||
};
|
||||
const o = section.option(form.DummyValue, "_mount_node");
|
||||
o.rawhtml = true;
|
||||
o.cfgvalue = () => {
|
||||
main.DashboardTab.initController();
|
||||
return main.DashboardTab.render();
|
||||
};
|
||||
}
|
||||
|
||||
const EntryPoint = {
|
||||
createDashboardContent,
|
||||
createDashboardContent,
|
||||
};
|
||||
|
||||
return baseclass.extend(EntryPoint);
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
'use strict';
|
||||
'require baseclass';
|
||||
'require form';
|
||||
'require ui';
|
||||
'require uci';
|
||||
'require fs';
|
||||
'require view.podkop.main as main';
|
||||
"use strict";
|
||||
"require baseclass";
|
||||
"require form";
|
||||
"require ui";
|
||||
"require uci";
|
||||
"require fs";
|
||||
"require view.podkop.main as main";
|
||||
|
||||
function createDiagnosticContent(section) {
|
||||
const o = section.option(form.DummyValue, '_mount_node');
|
||||
o.rawhtml = true;
|
||||
o.cfgvalue = () => {
|
||||
main.DiagnosticTab.initController();
|
||||
return main.DiagnosticTab.render();
|
||||
};
|
||||
const o = section.option(form.DummyValue, "_mount_node");
|
||||
o.rawhtml = true;
|
||||
o.cfgvalue = () => {
|
||||
main.DiagnosticTab.initController();
|
||||
return main.DiagnosticTab.render();
|
||||
};
|
||||
}
|
||||
|
||||
const EntryPoint = {
|
||||
createDiagnosticContent,
|
||||
createDiagnosticContent,
|
||||
};
|
||||
|
||||
return baseclass.extend(EntryPoint);
|
||||
|
||||
@@ -1,77 +1,98 @@
|
||||
'use strict';
|
||||
'require view';
|
||||
'require form';
|
||||
'require baseclass';
|
||||
'require network';
|
||||
'require view.podkop.main as main';
|
||||
"use strict";
|
||||
"require view";
|
||||
"require form";
|
||||
"require baseclass";
|
||||
"require network";
|
||||
"require view.podkop.main as main";
|
||||
|
||||
// Settings content
|
||||
'require view.podkop.settings as settings';
|
||||
"require view.podkop.settings as settings";
|
||||
|
||||
// Sections content
|
||||
'require view.podkop.section as section';
|
||||
"require view.podkop.section as section";
|
||||
|
||||
// Dashboard content
|
||||
'require view.podkop.dashboard as dashboard';
|
||||
"require view.podkop.dashboard as dashboard";
|
||||
|
||||
// Diagnostic content
|
||||
'require view.podkop.diagnostic as diagnostic';
|
||||
|
||||
"require view.podkop.diagnostic as diagnostic";
|
||||
|
||||
const EntryPoint = {
|
||||
async render() {
|
||||
main.injectGlobalStyles();
|
||||
|
||||
const podkopMap = new form.Map('podkop', _('Podkop Settings'), _('Configuration for Podkop service'));
|
||||
const podkopMap = new form.Map(
|
||||
"podkop",
|
||||
_("Podkop Settings"),
|
||||
_("Configuration for Podkop service"),
|
||||
);
|
||||
// Enable tab views
|
||||
podkopMap.tabbed = true;
|
||||
|
||||
// Sections tab
|
||||
const sectionsSection = podkopMap.section(form.TypedSection, 'section', _('Sections'));
|
||||
const sectionsSection = podkopMap.section(
|
||||
form.TypedSection,
|
||||
"section",
|
||||
_("Sections"),
|
||||
);
|
||||
sectionsSection.anonymous = false;
|
||||
sectionsSection.addremove = true;
|
||||
sectionsSection.template = 'cbi/simpleform';
|
||||
sectionsSection.template = "cbi/simpleform";
|
||||
|
||||
// Render section content
|
||||
section.createSectionContent(sectionsSection);
|
||||
|
||||
// Settings tab
|
||||
const settingsSection = podkopMap.section(form.TypedSection, 'settings', _('Settings'));
|
||||
const settingsSection = podkopMap.section(
|
||||
form.TypedSection,
|
||||
"settings",
|
||||
_("Settings"),
|
||||
);
|
||||
settingsSection.anonymous = true;
|
||||
settingsSection.addremove = false;
|
||||
// Make it named [ config settings 'settings' ]
|
||||
settingsSection.cfgsections = function () { return ['settings']; };
|
||||
settingsSection.cfgsections = function () {
|
||||
return ["settings"];
|
||||
};
|
||||
|
||||
// Render settings content
|
||||
settings.createSettingsContent(settingsSection);
|
||||
|
||||
|
||||
// Diagnostic tab
|
||||
const diagnosticSection = podkopMap.section(form.TypedSection, 'diagnostic', _('Diagnostics'));
|
||||
const diagnosticSection = podkopMap.section(
|
||||
form.TypedSection,
|
||||
"diagnostic",
|
||||
_("Diagnostics"),
|
||||
);
|
||||
diagnosticSection.anonymous = true;
|
||||
diagnosticSection.addremove = false;
|
||||
diagnosticSection.cfgsections = function () { return ['diagnostic']; };
|
||||
diagnosticSection.cfgsections = function () {
|
||||
return ["diagnostic"];
|
||||
};
|
||||
|
||||
// Render diagnostic content
|
||||
diagnostic.createDiagnosticContent(diagnosticSection);
|
||||
|
||||
// Dashboard tab
|
||||
const dashboardSection = podkopMap.section(form.TypedSection, 'dashboard', _('Dashboard'));
|
||||
const dashboardSection = podkopMap.section(
|
||||
form.TypedSection,
|
||||
"dashboard",
|
||||
_("Dashboard"),
|
||||
);
|
||||
dashboardSection.anonymous = true;
|
||||
dashboardSection.addremove = false;
|
||||
dashboardSection.cfgsections = function () { return ['dashboard']; };
|
||||
dashboardSection.cfgsections = function () {
|
||||
return ["dashboard"];
|
||||
};
|
||||
|
||||
// Render dashboard content
|
||||
dashboard.createDashboardContent(dashboardSection);
|
||||
|
||||
|
||||
|
||||
// Inject core service
|
||||
main.coreService();
|
||||
|
||||
return podkopMap.render();
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
};
|
||||
|
||||
return view.extend(EntryPoint);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,394 +1,394 @@
|
||||
'use strict';
|
||||
'require form';
|
||||
'require uci';
|
||||
'require baseclass';
|
||||
'require tools.widgets as widgets';
|
||||
'require view.podkop.main as main';
|
||||
"use strict";
|
||||
"require form";
|
||||
"require uci";
|
||||
"require baseclass";
|
||||
"require tools.widgets as widgets";
|
||||
"require view.podkop.main as main";
|
||||
|
||||
function createSettingsContent(section) {
|
||||
let o = section.option(
|
||||
form.ListValue,
|
||||
'dns_type',
|
||||
_('DNS Protocol Type'),
|
||||
_('Select DNS protocol to use'),
|
||||
);
|
||||
o.value('doh', _('DNS over HTTPS (DoH)'));
|
||||
o.value('dot', _('DNS over TLS (DoT)'));
|
||||
o.value('udp', _('UDP (Unprotected DNS)'));
|
||||
o.default = 'udp';
|
||||
o.rmempty = false;
|
||||
let o = section.option(
|
||||
form.ListValue,
|
||||
"dns_type",
|
||||
_("DNS Protocol Type"),
|
||||
_("Select DNS protocol to use"),
|
||||
);
|
||||
o.value("doh", _("DNS over HTTPS (DoH)"));
|
||||
o.value("dot", _("DNS over TLS (DoT)"));
|
||||
o.value("udp", _("UDP (Unprotected DNS)"));
|
||||
o.default = "udp";
|
||||
o.rmempty = false;
|
||||
|
||||
o = section.option(
|
||||
form.Value,
|
||||
'dns_server',
|
||||
_('DNS Server'),
|
||||
_('Select or enter DNS server address'),
|
||||
);
|
||||
Object.entries(main.DNS_SERVER_OPTIONS).forEach(([key, label]) => {
|
||||
o.value(key, _(label));
|
||||
});
|
||||
o.default = '8.8.8.8';
|
||||
o.rmempty = false;
|
||||
o.validate = function (section_id, value) {
|
||||
const validation = main.validateDNS(value);
|
||||
o = section.option(
|
||||
form.Value,
|
||||
"dns_server",
|
||||
_("DNS Server"),
|
||||
_("Select or enter DNS server address"),
|
||||
);
|
||||
Object.entries(main.DNS_SERVER_OPTIONS).forEach(([key, label]) => {
|
||||
o.value(key, _(label));
|
||||
});
|
||||
o.default = "8.8.8.8";
|
||||
o.rmempty = false;
|
||||
o.validate = function (section_id, value) {
|
||||
const validation = main.validateDNS(value);
|
||||
|
||||
if (validation.valid) {
|
||||
return true;
|
||||
}
|
||||
if (validation.valid) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return validation.message;
|
||||
};
|
||||
return validation.message;
|
||||
};
|
||||
|
||||
o = section.option(
|
||||
form.Value,
|
||||
'bootstrap_dns_server',
|
||||
_('Bootstrap DNS server'),
|
||||
_(
|
||||
'The DNS server used to look up the IP address of an upstream DNS server',
|
||||
),
|
||||
);
|
||||
Object.entries(main.BOOTSTRAP_DNS_SERVER_OPTIONS).forEach(([key, label]) => {
|
||||
o.value(key, _(label));
|
||||
});
|
||||
o.default = '77.88.8.8';
|
||||
o.rmempty = false;
|
||||
o.validate = function (section_id, value) {
|
||||
const validation = main.validateDNS(value);
|
||||
o = section.option(
|
||||
form.Value,
|
||||
"bootstrap_dns_server",
|
||||
_("Bootstrap DNS server"),
|
||||
_(
|
||||
"The DNS server used to look up the IP address of an upstream DNS server",
|
||||
),
|
||||
);
|
||||
Object.entries(main.BOOTSTRAP_DNS_SERVER_OPTIONS).forEach(([key, label]) => {
|
||||
o.value(key, _(label));
|
||||
});
|
||||
o.default = "77.88.8.8";
|
||||
o.rmempty = false;
|
||||
o.validate = function (section_id, value) {
|
||||
const validation = main.validateDNS(value);
|
||||
|
||||
if (validation.valid) {
|
||||
return true;
|
||||
}
|
||||
if (validation.valid) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return validation.message;
|
||||
};
|
||||
return validation.message;
|
||||
};
|
||||
|
||||
o = section.option(
|
||||
form.Value,
|
||||
'dns_rewrite_ttl',
|
||||
_('DNS Rewrite TTL'),
|
||||
_('Time in seconds for DNS record caching (default: 60)'),
|
||||
);
|
||||
o.default = '60';
|
||||
o.rmempty = false;
|
||||
o.validate = function (section_id, value) {
|
||||
if (!value) {
|
||||
return _('TTL value cannot be empty');
|
||||
}
|
||||
o = section.option(
|
||||
form.Value,
|
||||
"dns_rewrite_ttl",
|
||||
_("DNS Rewrite TTL"),
|
||||
_("Time in seconds for DNS record caching (default: 60)"),
|
||||
);
|
||||
o.default = "60";
|
||||
o.rmempty = false;
|
||||
o.validate = function (section_id, value) {
|
||||
if (!value) {
|
||||
return _("TTL value cannot be empty");
|
||||
}
|
||||
|
||||
const ttl = parseInt(value);
|
||||
if (isNaN(ttl) || ttl < 0) {
|
||||
return _('TTL must be a positive number');
|
||||
}
|
||||
const ttl = parseInt(value);
|
||||
if (isNaN(ttl) || ttl < 0) {
|
||||
return _("TTL must be a positive number");
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
return true;
|
||||
};
|
||||
|
||||
o = section.option(
|
||||
form.Flag,
|
||||
'enable_output_network_interface',
|
||||
_('Enable Output Network Interface'),
|
||||
_('You can select Output Network Interface, by default autodetect'),
|
||||
);
|
||||
o.default = '0';
|
||||
o.rmempty = false;
|
||||
o = section.option(
|
||||
form.Flag,
|
||||
"enable_output_network_interface",
|
||||
_("Enable Output Network Interface"),
|
||||
_("You can select Output Network Interface, by default autodetect"),
|
||||
);
|
||||
o.default = "0";
|
||||
o.rmempty = false;
|
||||
|
||||
o = section.option(
|
||||
widgets.DeviceSelect,
|
||||
'output_network_interface',
|
||||
_('Output Network Interface'),
|
||||
_('Select the network interface to which the traffic will originate'),
|
||||
);
|
||||
o.noaliases = true;
|
||||
o.multiple = false;
|
||||
o.depends('enable_output_network_interface', '1');
|
||||
o.filter = function (section_id, value) {
|
||||
// Blocked interface names that should never be selectable
|
||||
const blockedInterfaces = ['br-lan'];
|
||||
o = section.option(
|
||||
widgets.DeviceSelect,
|
||||
"output_network_interface",
|
||||
_("Output Network Interface"),
|
||||
_("Select the network interface to which the traffic will originate"),
|
||||
);
|
||||
o.noaliases = true;
|
||||
o.multiple = false;
|
||||
o.depends("enable_output_network_interface", "1");
|
||||
o.filter = function (section_id, value) {
|
||||
// Blocked interface names that should never be selectable
|
||||
const blockedInterfaces = ["br-lan"];
|
||||
|
||||
// Reject immediately if the value matches any blocked interface
|
||||
if (blockedInterfaces.includes(value)) {
|
||||
return false;
|
||||
}
|
||||
// Reject immediately if the value matches any blocked interface
|
||||
if (blockedInterfaces.includes(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Reject tun*, wg*, vpn*, awg*, oc*
|
||||
if (
|
||||
value.startsWith('tun') ||
|
||||
value.startsWith('wg') ||
|
||||
value.startsWith('vpn') ||
|
||||
value.startsWith('awg') ||
|
||||
value.startsWith('oc')
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
// Reject tun*, wg*, vpn*, awg*, oc*
|
||||
if (
|
||||
value.startsWith("tun") ||
|
||||
value.startsWith("wg") ||
|
||||
value.startsWith("vpn") ||
|
||||
value.startsWith("awg") ||
|
||||
value.startsWith("oc")
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try to find the device object with the given name
|
||||
const device = this.devices.find((dev) => dev.getName() === value);
|
||||
// Try to find the device object with the given name
|
||||
const device = this.devices.find((dev) => dev.getName() === value);
|
||||
|
||||
// If no device is found, allow the value
|
||||
if (!device) {
|
||||
return true;
|
||||
}
|
||||
// If no device is found, allow the value
|
||||
if (!device) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get the device type (e.g., "wifi", "ethernet", etc.)
|
||||
const type = device.getType();
|
||||
// Get the device type (e.g., "wifi", "ethernet", etc.)
|
||||
const type = device.getType();
|
||||
|
||||
// Reject wireless-related devices
|
||||
const isWireless =
|
||||
type === 'wifi' || type === 'wireless' || type.includes('wlan');
|
||||
// Reject wireless-related devices
|
||||
const isWireless =
|
||||
type === "wifi" || type === "wireless" || type.includes("wlan");
|
||||
|
||||
return !isWireless;
|
||||
};
|
||||
return !isWireless;
|
||||
};
|
||||
|
||||
o = section.option(
|
||||
widgets.DeviceSelect,
|
||||
'source_network_interfaces',
|
||||
_('Source Network Interface'),
|
||||
_('Select the network interface from which the traffic will originate'),
|
||||
);
|
||||
o.default = 'br-lan';
|
||||
o.noaliases = true;
|
||||
o.nobridges = false;
|
||||
o.noinactive = false;
|
||||
o.multiple = true;
|
||||
o.filter = function (section_id, value) {
|
||||
// Block specific interface names from being selectable
|
||||
const blocked = ['wan', 'phy0-ap0', 'phy1-ap0', 'pppoe-wan'];
|
||||
if (blocked.includes(value)) {
|
||||
return false;
|
||||
}
|
||||
o = section.option(
|
||||
widgets.DeviceSelect,
|
||||
"source_network_interfaces",
|
||||
_("Source Network Interface"),
|
||||
_("Select the network interface from which the traffic will originate"),
|
||||
);
|
||||
o.default = "br-lan";
|
||||
o.noaliases = true;
|
||||
o.nobridges = false;
|
||||
o.noinactive = false;
|
||||
o.multiple = true;
|
||||
o.filter = function (section_id, value) {
|
||||
// Block specific interface names from being selectable
|
||||
const blocked = ["wan", "phy0-ap0", "phy1-ap0", "pppoe-wan"];
|
||||
if (blocked.includes(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try to find the device object by its name
|
||||
const device = this.devices.find((dev) => dev.getName() === value);
|
||||
// Try to find the device object by its name
|
||||
const device = this.devices.find((dev) => dev.getName() === value);
|
||||
|
||||
// If no device is found, allow the value
|
||||
if (!device) {
|
||||
return true;
|
||||
}
|
||||
// If no device is found, allow the value
|
||||
if (!device) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check the type of the device
|
||||
const type = device.getType();
|
||||
// Check the type of the device
|
||||
const type = device.getType();
|
||||
|
||||
// Consider any Wi-Fi / wireless / wlan device as invalid
|
||||
const isWireless =
|
||||
type === 'wifi' || type === 'wireless' || type.includes('wlan');
|
||||
// Consider any Wi-Fi / wireless / wlan device as invalid
|
||||
const isWireless =
|
||||
type === "wifi" || type === "wireless" || type.includes("wlan");
|
||||
|
||||
// Allow only non-wireless devices
|
||||
return !isWireless;
|
||||
};
|
||||
// Allow only non-wireless devices
|
||||
return !isWireless;
|
||||
};
|
||||
|
||||
o = section.option(
|
||||
form.Flag,
|
||||
'enable_badwan_interface_monitoring',
|
||||
_('Interface Monitoring'),
|
||||
_('Interface monitoring for Bad WAN'),
|
||||
);
|
||||
o.default = '0';
|
||||
o.rmempty = false;
|
||||
o = section.option(
|
||||
form.Flag,
|
||||
"enable_badwan_interface_monitoring",
|
||||
_("Interface Monitoring"),
|
||||
_("Interface monitoring for Bad WAN"),
|
||||
);
|
||||
o.default = "0";
|
||||
o.rmempty = false;
|
||||
|
||||
o = section.option(
|
||||
widgets.NetworkSelect,
|
||||
'badwan_monitored_interfaces',
|
||||
_('Monitored Interfaces'),
|
||||
_('Select the WAN interfaces to be monitored'),
|
||||
);
|
||||
o.depends('enable_badwan_interface_monitoring', '1');
|
||||
o.multiple = true;
|
||||
o.filter = function (section_id, value) {
|
||||
// Reject if the value is in the blocked list ['lan', 'loopback']
|
||||
if (['lan', 'loopback'].includes(value)) {
|
||||
return false;
|
||||
}
|
||||
o = section.option(
|
||||
widgets.NetworkSelect,
|
||||
"badwan_monitored_interfaces",
|
||||
_("Monitored Interfaces"),
|
||||
_("Select the WAN interfaces to be monitored"),
|
||||
);
|
||||
o.depends("enable_badwan_interface_monitoring", "1");
|
||||
o.multiple = true;
|
||||
o.filter = function (section_id, value) {
|
||||
// Reject if the value is in the blocked list ['lan', 'loopback']
|
||||
if (["lan", "loopback"].includes(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Reject if the value starts with '@' (means it's an alias/reference)
|
||||
if (value.startsWith('@')) {
|
||||
return false;
|
||||
}
|
||||
// Reject if the value starts with '@' (means it's an alias/reference)
|
||||
if (value.startsWith("@")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise allow it
|
||||
return true;
|
||||
};
|
||||
// Otherwise allow it
|
||||
return true;
|
||||
};
|
||||
|
||||
o = section.option(
|
||||
form.Value,
|
||||
'badwan_reload_delay',
|
||||
_('Interface Monitoring Delay'),
|
||||
_('Delay in milliseconds before reloading podkop after interface UP'),
|
||||
);
|
||||
o.depends('enable_badwan_interface_monitoring', '1');
|
||||
o.default = '2000';
|
||||
o.rmempty = false;
|
||||
o.validate = function (section_id, value) {
|
||||
if (!value) {
|
||||
return _('Delay value cannot be empty');
|
||||
}
|
||||
return true;
|
||||
};
|
||||
o = section.option(
|
||||
form.Value,
|
||||
"badwan_reload_delay",
|
||||
_("Interface Monitoring Delay"),
|
||||
_("Delay in milliseconds before reloading podkop after interface UP"),
|
||||
);
|
||||
o.depends("enable_badwan_interface_monitoring", "1");
|
||||
o.default = "2000";
|
||||
o.rmempty = false;
|
||||
o.validate = function (section_id, value) {
|
||||
if (!value) {
|
||||
return _("Delay value cannot be empty");
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
o = section.option(
|
||||
form.Flag,
|
||||
'enable_yacd',
|
||||
_('Enable YACD'),
|
||||
`<a href="${main.getClashUIUrl()}" target="_blank">${main.getClashUIUrl()}</a>`,
|
||||
);
|
||||
o.default = '0';
|
||||
o.rmempty = false;
|
||||
o = section.option(
|
||||
form.Flag,
|
||||
"enable_yacd",
|
||||
_("Enable YACD"),
|
||||
`<a href="${main.getClashUIUrl()}" target="_blank">${main.getClashUIUrl()}</a>`,
|
||||
);
|
||||
o.default = "0";
|
||||
o.rmempty = false;
|
||||
|
||||
o = section.option(
|
||||
form.Flag,
|
||||
'disable_quic',
|
||||
_('Disable QUIC'),
|
||||
_(
|
||||
'Disable the QUIC protocol to improve compatibility or fix issues with video streaming',
|
||||
),
|
||||
);
|
||||
o.default = '0';
|
||||
o.rmempty = false;
|
||||
o = section.option(
|
||||
form.Flag,
|
||||
"disable_quic",
|
||||
_("Disable QUIC"),
|
||||
_(
|
||||
"Disable the QUIC protocol to improve compatibility or fix issues with video streaming",
|
||||
),
|
||||
);
|
||||
o.default = "0";
|
||||
o.rmempty = false;
|
||||
|
||||
o = section.option(
|
||||
form.ListValue,
|
||||
'update_interval',
|
||||
_('List Update Frequency'),
|
||||
_('Select how often the domain or subnet lists are updated automatically'),
|
||||
);
|
||||
Object.entries(main.UPDATE_INTERVAL_OPTIONS).forEach(([key, label]) => {
|
||||
o.value(key, _(label));
|
||||
});
|
||||
o.default = '1d';
|
||||
o.rmempty = false;
|
||||
o = section.option(
|
||||
form.ListValue,
|
||||
"update_interval",
|
||||
_("List Update Frequency"),
|
||||
_("Select how often the domain or subnet lists are updated automatically"),
|
||||
);
|
||||
Object.entries(main.UPDATE_INTERVAL_OPTIONS).forEach(([key, label]) => {
|
||||
o.value(key, _(label));
|
||||
});
|
||||
o.default = "1d";
|
||||
o.rmempty = false;
|
||||
|
||||
o = section.option(
|
||||
form.Flag,
|
||||
'download_lists_via_proxy',
|
||||
_('Download Lists via Proxy/VPN'),
|
||||
_('Downloading all lists via main Proxy/VPN'),
|
||||
);
|
||||
o.default = '0';
|
||||
o.rmempty = false;
|
||||
o = section.option(
|
||||
form.Flag,
|
||||
"download_lists_via_proxy",
|
||||
_("Download Lists via Proxy/VPN"),
|
||||
_("Downloading all lists via main Proxy/VPN"),
|
||||
);
|
||||
o.default = "0";
|
||||
o.rmempty = false;
|
||||
|
||||
o = section.option(
|
||||
form.ListValue,
|
||||
'download_lists_via_proxy_section',
|
||||
_('Download Lists via specific proxy section'),
|
||||
_('Downloading all lists via specific Proxy/VPN'),
|
||||
);
|
||||
o = section.option(
|
||||
form.ListValue,
|
||||
"download_lists_via_proxy_section",
|
||||
_("Download Lists via specific proxy section"),
|
||||
_("Downloading all lists via specific Proxy/VPN"),
|
||||
);
|
||||
|
||||
o.rmempty = false;
|
||||
o.depends('download_lists_via_proxy', '1');
|
||||
o.cfgvalue = function (section_id) {
|
||||
return uci.get('podkop', section_id, 'download_lists_via_proxy_section');
|
||||
};
|
||||
o.load = function () {
|
||||
const sections = this.map?.data?.state?.values?.podkop ?? {};
|
||||
o.rmempty = false;
|
||||
o.depends("download_lists_via_proxy", "1");
|
||||
o.cfgvalue = function (section_id) {
|
||||
return uci.get("podkop", section_id, "download_lists_via_proxy_section");
|
||||
};
|
||||
o.load = function () {
|
||||
const sections = this.map?.data?.state?.values?.podkop ?? {};
|
||||
|
||||
this.keylist = [];
|
||||
this.vallist = [];
|
||||
this.keylist = [];
|
||||
this.vallist = [];
|
||||
|
||||
for (const secName in sections) {
|
||||
const sec = sections[secName];
|
||||
if (sec['.type'] === 'section') {
|
||||
this.keylist.push(secName);
|
||||
this.vallist.push(secName);
|
||||
}
|
||||
}
|
||||
for (const secName in sections) {
|
||||
const sec = sections[secName];
|
||||
if (sec[".type"] === "section") {
|
||||
this.keylist.push(secName);
|
||||
this.vallist.push(secName);
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
};
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
o = section.option(
|
||||
form.Flag,
|
||||
'dont_touch_dhcp',
|
||||
_('Dont Touch My DHCP!'),
|
||||
_('Podkop will not modify your DHCP configuration'),
|
||||
);
|
||||
o.default = '0';
|
||||
o.rmempty = false;
|
||||
o = section.option(
|
||||
form.Flag,
|
||||
"dont_touch_dhcp",
|
||||
_("Dont Touch My DHCP!"),
|
||||
_("Podkop will not modify your DHCP configuration"),
|
||||
);
|
||||
o.default = "0";
|
||||
o.rmempty = false;
|
||||
|
||||
o = section.option(
|
||||
form.ListValue,
|
||||
'config_path',
|
||||
_('Config File Path'),
|
||||
_(
|
||||
'Select path for sing-box config file. Change this ONLY if you know what you are doing',
|
||||
),
|
||||
);
|
||||
o.value('/etc/sing-box/config.json', 'Flash (/etc/sing-box/config.json)');
|
||||
o.value('/tmp/sing-box/config.json', 'RAM (/tmp/sing-box/config.json)');
|
||||
o.default = '/etc/sing-box/config.json';
|
||||
o.rmempty = false;
|
||||
o = section.option(
|
||||
form.ListValue,
|
||||
"config_path",
|
||||
_("Config File Path"),
|
||||
_(
|
||||
"Select path for sing-box config file. Change this ONLY if you know what you are doing",
|
||||
),
|
||||
);
|
||||
o.value("/etc/sing-box/config.json", "Flash (/etc/sing-box/config.json)");
|
||||
o.value("/tmp/sing-box/config.json", "RAM (/tmp/sing-box/config.json)");
|
||||
o.default = "/etc/sing-box/config.json";
|
||||
o.rmempty = false;
|
||||
|
||||
o = section.option(
|
||||
form.Value,
|
||||
'cache_path',
|
||||
_('Cache File Path'),
|
||||
_(
|
||||
'Select or enter path for sing-box cache file. Change this ONLY if you know what you are doing',
|
||||
),
|
||||
);
|
||||
o.value('/tmp/sing-box/cache.db', 'RAM (/tmp/sing-box/cache.db)');
|
||||
o.value(
|
||||
'/usr/share/sing-box/cache.db',
|
||||
'Flash (/usr/share/sing-box/cache.db)',
|
||||
);
|
||||
o.default = '/tmp/sing-box/cache.db';
|
||||
o.rmempty = false;
|
||||
o.validate = function (section_id, value) {
|
||||
if (!value) {
|
||||
return _('Cache file path cannot be empty');
|
||||
}
|
||||
o = section.option(
|
||||
form.Value,
|
||||
"cache_path",
|
||||
_("Cache File Path"),
|
||||
_(
|
||||
"Select or enter path for sing-box cache file. Change this ONLY if you know what you are doing",
|
||||
),
|
||||
);
|
||||
o.value("/tmp/sing-box/cache.db", "RAM (/tmp/sing-box/cache.db)");
|
||||
o.value(
|
||||
"/usr/share/sing-box/cache.db",
|
||||
"Flash (/usr/share/sing-box/cache.db)",
|
||||
);
|
||||
o.default = "/tmp/sing-box/cache.db";
|
||||
o.rmempty = false;
|
||||
o.validate = function (section_id, value) {
|
||||
if (!value) {
|
||||
return _("Cache file path cannot be empty");
|
||||
}
|
||||
|
||||
if (!value.startsWith('/')) {
|
||||
return _('Path must be absolute (start with /)');
|
||||
}
|
||||
if (!value.startsWith("/")) {
|
||||
return _("Path must be absolute (start with /)");
|
||||
}
|
||||
|
||||
if (!value.endsWith('cache.db')) {
|
||||
return _('Path must end with cache.db');
|
||||
}
|
||||
if (!value.endsWith("cache.db")) {
|
||||
return _("Path must end with cache.db");
|
||||
}
|
||||
|
||||
const parts = value.split('/').filter(Boolean);
|
||||
if (parts.length < 2) {
|
||||
return _('Path must contain at least one directory (like /tmp/cache.db)');
|
||||
}
|
||||
const parts = value.split("/").filter(Boolean);
|
||||
if (parts.length < 2) {
|
||||
return _("Path must contain at least one directory (like /tmp/cache.db)");
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
return true;
|
||||
};
|
||||
|
||||
o = section.option(
|
||||
form.Flag,
|
||||
'exclude_ntp',
|
||||
_('Exclude NTP'),
|
||||
_(
|
||||
'Exclude NTP protocol traffic from the tunnel to prevent it from being routed through the proxy or VPN',
|
||||
),
|
||||
);
|
||||
o.default = '0';
|
||||
o.rmempty = false;
|
||||
o = section.option(
|
||||
form.Flag,
|
||||
"exclude_ntp",
|
||||
_("Exclude NTP"),
|
||||
_(
|
||||
"Exclude NTP protocol traffic from the tunnel to prevent it from being routed through the proxy or VPN",
|
||||
),
|
||||
);
|
||||
o.default = "0";
|
||||
o.rmempty = false;
|
||||
|
||||
o = section.option(
|
||||
form.DynamicList,
|
||||
'routing_excluded_ips',
|
||||
_('Routing Excluded IPs'),
|
||||
_('Specify a local IP address to be excluded from routing'),
|
||||
);
|
||||
o.placeholder = 'IP';
|
||||
o.rmempty = true;
|
||||
o.validate = function (section_id, value) {
|
||||
// Optional
|
||||
if (!value || value.length === 0) {
|
||||
return true;
|
||||
}
|
||||
o = section.option(
|
||||
form.DynamicList,
|
||||
"routing_excluded_ips",
|
||||
_("Routing Excluded IPs"),
|
||||
_("Specify a local IP address to be excluded from routing"),
|
||||
);
|
||||
o.placeholder = "IP";
|
||||
o.rmempty = true;
|
||||
o.validate = function (section_id, value) {
|
||||
// Optional
|
||||
if (!value || value.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const validation = main.validateIPV4(value);
|
||||
const validation = main.validateIPV4(value);
|
||||
|
||||
if (validation.valid) {
|
||||
return true;
|
||||
}
|
||||
if (validation.valid) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return validation.message;
|
||||
};
|
||||
return validation.message;
|
||||
};
|
||||
}
|
||||
|
||||
const EntryPoint = {
|
||||
createSettingsContent,
|
||||
createSettingsContent,
|
||||
};
|
||||
|
||||
return baseclass.extend(EntryPoint);
|
||||
|
||||
Reference in New Issue
Block a user