update 2026-07-13 00:53:40

This commit is contained in:
action
2026-07-13 00:53:40 +08:00
parent 192d5e4fd9
commit dc61ff94d8
41 changed files with 750 additions and 549 deletions
@@ -325,7 +325,7 @@ return baseclass.extend({
if (!value)
return _('Expecting: %s').format(_('non-empty value'));
else if (value.match('^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$') === null)
return _('Expecting: %s').format(_('valid uuid'));
return _('Expecting: %s').format(_('valid UUID'));
}
return true;
@@ -221,7 +221,7 @@ return view.extend({
o = s.taboption('routing', form.Value, 'dns_server', _('DNS server'),
_('Support UDP, TCP, DoH, DoQ, DoT. TCP protocol will be used if not specified.'));
o.value('wan', _('WAN DNS (read from interface)'));
o.value('https://dns.cloudflare.com/dns-query', _('CloudFlare Public DNS (DoH)'));
o.value('https://dns.cloudflare.com/dns-query', _('Cloudflare Public DNS (DoH)'));
o.value('https://dns.google/dns-query', _('Google Public DNS (DoH)'));
o.value('https://dns.quad9.net/dns-query', _('Quad9 Public DNS (DoH)'));
o.value('https://dns.adguard-dns.com/dns-query', _('AdGuard Public DNS (DoH)'));
@@ -260,7 +260,7 @@ return view.extend({
o.value('wan', _('WAN DNS (read from interface)'));
o.value('https://doh-pure.onedns.net/dns-query', _('ThreatBook Public DNS (DoH)'));
o.value('https://doh.pub/dns-query', _('Tencent Public DNS (DoH)'));
o.value('https://dns.alidns.com/dns-query', _('AliYun Public DNS (DoH)'));
o.value('https://dns.alidns.com/dns-query', _('AliDNS Public DNS (DoH)'));
o.depends('routing_mode', 'bypass_mainland_china');
o.default = 'https://dns.alidns.com/dns-query';
o.rmempty = false;
@@ -313,7 +313,7 @@ return view.extend({
if (!stubValidator.apply('port', i) && !stubValidator.apply('portrange', i))
return _('Expecting: %s').format(_('valid port value'));
if (ports.includes(i))
return _('Port %s alrealy exists!').format(i);
return _('Port %s already exists!').format(i);
ports = ports.concat(i);
}
}
@@ -748,7 +748,7 @@ return view.extend({
so.modalonly = true;
so = ss.taboption('field_other', form.Value, 'udp_timeout', _('UDP timeout'),
_('Timeout for UDP connections.<br/>Setting a larger value than the UDP timeout in inbounds will have no effect.'));
_('Timeout for UDP connections.<br/>Setting a larger value than the inbound UDP timeout will have no effect.'));
so.datatype = 'uinteger';
so.depends('action', 'route');
so.depends('action', 'route-options');
@@ -830,7 +830,7 @@ return view.extend({
so.depends('action', 'resolve');
so.modalonly = true;
so = ss.taboption('field_host', form.DynamicList, 'domain', _('Domain name'),
so = ss.taboption('field_host', form.DynamicList, 'domain', _('Domains'),
_('Match full domain.'));
so.datatype = 'hostname';
so.modalonly = true;
@@ -1206,7 +1206,7 @@ return view.extend({
so.depends('action', 'route');
so.modalonly = true;
so = ss.taboption('field_other', form.Flag, 'dns_disable_cache', _('Disable dns cache'),
so = ss.taboption('field_other', form.Flag, 'dns_disable_cache', _('Disable DNS cache'),
_('Disable cache and save cache in this query.'));
so.depends('action', 'route');
so.depends('action', 'route-options');
@@ -1267,7 +1267,7 @@ return view.extend({
so.depends('action', 'predefined');
so.modalonly = true;
so = ss.taboption('field_host', form.DynamicList, 'domain', _('Domain name'),
so = ss.taboption('field_host', form.DynamicList, 'domain', _('Domains'),
_('Match full domain.'));
so.datatype = 'hostname';
so.modalonly = true;
@@ -1431,7 +1431,7 @@ return view.extend({
ss = o.subsection;
/* Interface control start */
ss.tab('interface', _('Interface Control'));
ss.tab('interface', _('Interface control'));
so = ss.taboption('interface', widgets.DeviceSelect, 'listen_interfaces', _('Listen interfaces'),
_('Only process traffic from specific interfaces. Leave empty for all.'));
@@ -1454,55 +1454,55 @@ return view.extend({
so.default = 'disabled';
so.rmempty = false;
so = fwtool.addIPOption(ss, 'lan_ip_policy', 'lan_direct_ipv4_ips', _('Direct IPv4 IP-s'), null, 'ipv4', hosts, true);
so = fwtool.addIPOption(ss, 'lan_ip_policy', 'lan_direct_ipv4_ips', _('Direct IPv4 addresses'), null, 'ipv4', hosts, true);
so.depends('lan_proxy_mode', 'except_listed');
so = fwtool.addIPOption(ss, 'lan_ip_policy', 'lan_direct_ipv6_ips', _('Direct IPv6 IP-s'), null, 'ipv6', hosts, true);
so = fwtool.addIPOption(ss, 'lan_ip_policy', 'lan_direct_ipv6_ips', _('Direct IPv6 addresses'), null, 'ipv6', hosts, true);
so.depends({'lan_proxy_mode': 'except_listed', 'homeproxy.config.ipv6_support': '1'});
so = fwtool.addMACOption(ss, 'lan_ip_policy', 'lan_direct_mac_addrs', _('Direct MAC-s'), null, hosts);
so = fwtool.addMACOption(ss, 'lan_ip_policy', 'lan_direct_mac_addrs', _('Direct MAC addresses'), null, hosts);
so.depends('lan_proxy_mode', 'except_listed');
so = fwtool.addIPOption(ss, 'lan_ip_policy', 'lan_proxy_ipv4_ips', _('Proxy IPv4 IP-s'), null, 'ipv4', hosts, true);
so = fwtool.addIPOption(ss, 'lan_ip_policy', 'lan_proxy_ipv4_ips', _('Proxy IPv4 addresses'), null, 'ipv4', hosts, true);
so.depends('lan_proxy_mode', 'listed_only');
so = fwtool.addIPOption(ss, 'lan_ip_policy', 'lan_proxy_ipv6_ips', _('Proxy IPv6 IP-s'), null, 'ipv6', hosts, true);
so = fwtool.addIPOption(ss, 'lan_ip_policy', 'lan_proxy_ipv6_ips', _('Proxy IPv6 addresses'), null, 'ipv6', hosts, true);
so.depends({'lan_proxy_mode': 'listed_only', 'homeproxy.config.ipv6_support': '1'});
so = fwtool.addMACOption(ss, 'lan_ip_policy', 'lan_proxy_mac_addrs', _('Proxy MAC-s'), null, hosts);
so = fwtool.addMACOption(ss, 'lan_ip_policy', 'lan_proxy_mac_addrs', _('Proxy MAC addresses'), null, hosts);
so.depends('lan_proxy_mode', 'listed_only');
so = fwtool.addIPOption(ss, 'lan_ip_policy', 'lan_gaming_mode_ipv4_ips', _('Gaming mode IPv4 IP-s'), null, 'ipv4', hosts, true);
so = fwtool.addIPOption(ss, 'lan_ip_policy', 'lan_gaming_mode_ipv4_ips', _('Gaming mode IPv4 addresses'), null, 'ipv4', hosts, true);
so = fwtool.addIPOption(ss, 'lan_ip_policy', 'lan_gaming_mode_ipv6_ips', _('Gaming mode IPv6 IP-s'), null, 'ipv6', hosts, true);
so = fwtool.addIPOption(ss, 'lan_ip_policy', 'lan_gaming_mode_ipv6_ips', _('Gaming mode IPv6 addresses'), null, 'ipv6', hosts, true);
so.depends('homeproxy.config.ipv6_support', '1');
so = fwtool.addMACOption(ss, 'lan_ip_policy', 'lan_gaming_mode_mac_addrs', _('Gaming mode MAC-s'), null, hosts);
so = fwtool.addMACOption(ss, 'lan_ip_policy', 'lan_gaming_mode_mac_addrs', _('Gaming mode MAC addresses'), null, hosts);
so = fwtool.addIPOption(ss, 'lan_ip_policy', 'lan_global_proxy_ipv4_ips', _('Global proxy IPv4 IP-s'), null, 'ipv4', hosts, true);
so = fwtool.addIPOption(ss, 'lan_ip_policy', 'lan_global_proxy_ipv4_ips', _('Global proxy IPv4 addresses'), null, 'ipv4', hosts, true);
so.depends({'homeproxy.config.routing_mode': 'custom', '!reverse': true});
so = fwtool.addIPOption(ss, 'lan_ip_policy', 'lan_global_proxy_ipv6_ips', _('Global proxy IPv6 IP-s'), null, 'ipv6', hosts, true);
so = fwtool.addIPOption(ss, 'lan_ip_policy', 'lan_global_proxy_ipv6_ips', _('Global proxy IPv6 addresses'), null, 'ipv6', hosts, true);
so.depends({'homeproxy.config.routing_mode': /^((?!custom).)+$/, 'homeproxy.config.ipv6_support': '1'});
so = fwtool.addMACOption(ss, 'lan_ip_policy', 'lan_global_proxy_mac_addrs', _('Global proxy MAC-s'), null, hosts);
so = fwtool.addMACOption(ss, 'lan_ip_policy', 'lan_global_proxy_mac_addrs', _('Global proxy MAC addresses'), null, hosts);
so.depends({'homeproxy.config.routing_mode': 'custom', '!reverse': true});
/* LAN IP policy end */
/* WAN IP policy start */
ss.tab('wan_ip_policy', _('WAN IP Policy'));
so = ss.taboption('wan_ip_policy', form.DynamicList, 'wan_proxy_ipv4_ips', _('Proxy IPv4 IP-s'));
so = ss.taboption('wan_ip_policy', form.DynamicList, 'wan_proxy_ipv4_ips', _('Proxy IPv4 addresses'));
so.datatype = 'or(ip4addr, cidr4)';
so = ss.taboption('wan_ip_policy', form.DynamicList, 'wan_proxy_ipv6_ips', _('Proxy IPv6 IP-s'));
so = ss.taboption('wan_ip_policy', form.DynamicList, 'wan_proxy_ipv6_ips', _('Proxy IPv6 addresses'));
so.datatype = 'or(ip6addr, cidr6)';
so.depends('homeproxy.config.ipv6_support', '1');
so = ss.taboption('wan_ip_policy', form.DynamicList, 'wan_direct_ipv4_ips', _('Direct IPv4 IP-s'));
so = ss.taboption('wan_ip_policy', form.DynamicList, 'wan_direct_ipv4_ips', _('Direct IPv4 addresses'));
so.datatype = 'or(ip4addr, cidr4)';
so = ss.taboption('wan_ip_policy', form.DynamicList, 'wan_direct_ipv6_ips', _('Direct IPv6 IP-s'));
so = ss.taboption('wan_ip_policy', form.DynamicList, 'wan_direct_ipv6_ips', _('Direct IPv6 addresses'));
so.datatype = 'or(ip6addr, cidr6)';
so.depends('homeproxy.config.ipv6_support', '1');
/* WAN IP policy end */
@@ -1049,7 +1049,7 @@ function renderNodeSettings(section, data, features, main_node, routing_mode, no
o.modalonly = true;
o = s.option(form.ListValue, 'shadowsocks_plugin', _('Plugin'));
o.value('', _('none'));
o.value('', _('None'));
o.value('obfs-local');
o.value('v2ray-plugin');
o.depends('type', 'shadowsocks');
@@ -1305,9 +1305,9 @@ function renderNodeSettings(section, data, features, main_node, routing_mode, no
/* WebSocket config end */
o = s.option(form.ListValue, 'packet_encoding', _('Packet encoding'));
o.value('', _('none'));
o.value('', _('None'));
o.value('packetaddr', _('packet addr (v2ray-core v5+)'));
o.value('xudp', _('Xudp (Xray-core)'));
o.value('xudp', _('XUDP (Xray-core)'));
o.depends('type', 'vless');
o.depends('type', 'vmess');
o.modalonly = true;
@@ -1329,7 +1329,7 @@ function renderNodeSettings(section, data, features, main_node, routing_mode, no
o.rmempty = false;
o.modalonly = true;
o = s.option(form.Value, 'wireguard_peer_public_key', _('Peer pubkic key'),
o = s.option(form.Value, 'wireguard_peer_public_key', _('Peer public key'),
_('WireGuard peer public key.'));
o.depends('type', 'wireguard');
o.validate = L.bind(hp.validateBase64Key, this, 44);
@@ -1468,7 +1468,7 @@ function renderNodeSettings(section, data, features, main_node, routing_mode, no
o = s.option(form.ListValue, 'tls_min_version', _('Minimum TLS version'),
_('The minimum TLS version that is acceptable.'));
o.value('', _('default'));
o.value('', _('Default'));
for (let i of hp.tls_versions)
o.value(i);
o.depends('tls', '1');
@@ -1476,7 +1476,7 @@ function renderNodeSettings(section, data, features, main_node, routing_mode, no
o = s.option(form.ListValue, 'tls_max_version', _('Maximum TLS version'),
_('The maximum TLS version that is acceptable.'));
o.value('', _('default'));
o.value('', _('Default'));
for (let i of hp.tls_versions)
o.value(i);
o.depends('tls', '1');
@@ -1757,7 +1757,7 @@ return view.extend({
s.tab('subscription', _('Subscriptions'));
o = s.taboption('subscription', form.Flag, 'auto_update', _('Auto update'),
_('Auto update subscriptions and geodata.'));
_('Auto update subscriptions and resources.'));
o.rmempty = false;
o = s.taboption('subscription', form.Value, 'auto_update_time', _('Cron expression'),
@@ -1777,7 +1777,7 @@ return view.extend({
o.default = 'icmp';
o.rmempty = false;
o = s.taboption('subscription', form.DynamicList, 'subscription_url', _('Subscription URL-s'),
o = s.taboption('subscription', form.DynamicList, 'subscription_url', _('Subscription URLs'),
_('Support Hysteria, Shadowsocks, Trojan, v2rayN (VMess), and XTLS (VLESS) online configuration delivery standard.'));
o.validate = function(section_id, value) {
if (section_id && value) {
@@ -1811,16 +1811,16 @@ return view.extend({
o.placeholder = 'Wget/1.21 (HomeProxy, like v2rayN)';
o = s.taboption('subscription', form.Flag, 'allow_insecure', _('Allow insecure'),
_('Allow insecure connection by default when add nodes from subscriptions.') +
_('Allow insecure connection by default when adding nodes from subscriptions.') +
'<br/>' +
_('This is <strong>DANGEROUS</strong>, your traffic is almost like <strong>PLAIN TEXT</strong>! Use at your own risk!'));
o.rmempty = false;
o.onchange = allowInsecureConfirm;
o = s.taboption('subscription', form.ListValue, 'packet_encoding', _('Default packet encoding'));
o.value('', _('none'));
o.value('', _('None'));
o.value('packetaddr', _('packet addr (v2ray-core v5+)'));
o.value('xudp', _('Xudp (Xray-core)'));
o.value('xudp', _('XUDP (Xray-core)'));
o = s.taboption('subscription', form.Button, '_save_subscriptions', _('Save subscriptions settings'),
_('NOTE: Save current settings before updating subscriptions.'));
@@ -148,7 +148,7 @@ return view.extend({
o = s.option(form.Flag, 'enabled', _('Enable'));
o.rmempty = false;
s = m.section(form.GridSection, 'server', _('Server settings'));
s = m.section(form.GridSection, 'server', _('Server Settings'));
s.addremove = true;
s.rowcolors = true;
s.sortable = true;
@@ -329,7 +329,7 @@ return view.extend({
o.modalonly = true;
o = s.option(form.Value, 'hysteria_masquerade', _('Masquerade'),
_('HTTP3 server behavior when authentication fails.<br/>A 404 page will be returned if empty.'));
_('HTTP/3 server behavior when authentication fails.<br/>A 404 page will be returned if empty.'));
o.depends('type', 'hysteria2');
o.modalonly = true;
/* Hysteria (2) config end */
@@ -569,7 +569,7 @@ return view.extend({
o = s.option(form.ListValue, 'tls_min_version', _('Minimum TLS version'),
_('The minimum TLS version that is acceptable.'));
o.value('', _('default'));
o.value('', _('Default'));
for (let i of hp.tls_versions)
o.value(i);
o.depends('tls', '1');
@@ -577,7 +577,7 @@ return view.extend({
o = s.option(form.ListValue, 'tls_max_version', _('Maximum TLS version'),
_('The maximum TLS version that is acceptable.'));
o.value('', _('default'));
o.value('', _('Default'));
for (let i of hp.tls_versions)
o.value(i);
o.depends('tls', '1');
@@ -632,13 +632,13 @@ return view.extend({
o.rmempty = false;
o.modalonly = true;
o = s.option(form.Flag, 'tls_dns01_challenge', _('DNS01 challenge'))
o = s.option(form.Flag, 'tls_dns01_challenge', _('DNS-01 challenge'))
o.depends('tls_acme', '1');
o.modalonly = true;
o = s.option(form.ListValue, 'tls_dns01_provider', _('DNS provider'));
o.value('alidns', _('AliYun'));
o.value('cfdns', _('CloudFlare'));
o.value('alidns', _('AliDNS'));
o.value('cfdns', _('Cloudflare'));
o.depends('tls_dns01_challenge', '1');
o.default = 'cfdns';
o.rmempty = false;
@@ -788,7 +788,7 @@ return view.extend({
o.inputstyle = 'action';
o.inputtitle = _('Upload...');
o.depends({'tls': '1', 'tls_key_path': '/etc/homeproxy/certs/server_privatekey.pem'});
o.onclick = L.bind(hp.uploadCertificate, this, _('private key'), 'server_privatekey');
o.onclick = L.bind(hp.uploadCertificate, this, _('Private key'), 'server_privatekey');
o.modalonly = true;
o = s.option(form.TextValue, 'tls_ech_key', _('ECH key'));
@@ -89,11 +89,11 @@ function getConnectionStatus() {
if (result?.result) {
elements.state.style.setProperty('color', 'green');
dom.content(elements.state, _('Connected'));
dom.content(elements.latency, _('%d ms').format(result.latency_ms));
dom.content(elements.state, _('Success'));
dom.content(elements.latency, _('%s ms').format(result.latency_ms));
} else {
elements.state.style.setProperty('color', 'red');
dom.content(elements.state, result?.timed_out ? _('Timed out') : _('Disconnected'));
dom.content(elements.state, result?.timed_out ? _('Timed out') : _('Failed'));
dom.content(elements.latency, '-');
}
};