2020-06-19 20:43:08 +03:00
'use strict' ;
'require fs' ;
'require form' ;
'require tools.widgets as widgets' ;
2022-05-05 18:28:32 +03:00
'require uci' ;
'require ui' ;
2021-12-05 19:18:32 +03:00
'require view' ;
2020-06-19 20:43:08 +03:00
'require view.ruantiblock.tools as tools' ;
2021-12-05 19:18:32 +03:00
return view . extend ( {
2024-11-03 02:20:45 +03:00
parsers : { } ,
2021-11-04 18:57:08 +03:00
2024-11-03 02:20:45 +03:00
appStatusCode : null ,
2021-11-04 18:57:08 +03:00
2024-11-03 02:20:45 +03:00
depends ( elem , key , array , empty = true ) {
2021-11-04 18:57:08 +03:00
if ( empty && array . length === 0 ) {
elem . depends ( key , '_dummy' ) ;
} else {
array . forEach ( e => elem . depends ( key , e ) ) ;
} ;
} ,
2024-11-03 02:20:45 +03:00
validateIpPort ( section , value ) {
2021-11-04 18:57:08 +03:00
return ( /^$|^([0-9]{1,3}\.){3}[0-9]{1,3}(#[\d]{2,5})?$/ . test ( value ) ) ? true : _ ( 'Expecting:' )
+ ` ${ _ ( 'One of the following:' ) } \n - ${ _ ( 'valid IP address' ) } \n - ${ _ ( 'valid address#port' ) } \n ` ;
} ,
2024-11-03 02:20:45 +03:00
validateUrl ( section , value ) {
2025-12-16 20:19:03 +03:00
return ( /^$|^https?:\/\/[\w.-]+(:[0-9]{2,5})?((\/|\?).*)?$/ . test ( value ) ) ? true : _ ( 'Expecting:' )
2024-04-07 17:07:12 +03:00
+ ` ${ _ ( 'valid URL' ) } \n ` ;
} ,
2024-11-03 02:20:45 +03:00
CBIBlockFileEdit : form . Value . extend ( {
_ _name _ _ : 'CBI.BlockFileEdit' ,
_ _init _ _ ( map , section , ctx , id , file , title , description , callback ) {
this . map = map ;
this . section = section ;
this . ctx = ctx ;
this . id = id ,
this . optional = true ;
this . rmempty = true ;
this . file = file ;
this . title = title ;
this . description = description ;
this . callback = callback ;
this . content = '' ;
} ,
cfgvalue ( section _id , option ) {
return this . content ;
} ,
formvalue ( section _id ) {
let value = this . content ;
let textarea = document . getElementById ( 'widget.file_edit.content.' + this . id ) ;
if ( textarea ) {
value = textarea . value . trim ( ) . replace ( /\r\n/g , '\n' ) + '\n' ;
} ;
return value ;
} ,
write ( section _id , formvalue ) {
return fs . write ( this . file , formvalue ) . then ( rc => {
ui . addNotification ( null , E ( 'p' , _ ( 'Contents have been saved.' ) ) ,
'info' ) ;
if ( this . callback ) {
return this . callback ( rc ) ;
} ;
} ) . catch ( e => {
ui . addNotification ( null , E ( 'p' , _ ( 'Unable to save the contents' )
+ ': %s' . format ( e . message ) ) ) ;
} ) ;
} ,
load ( ) {
return L . resolveDefault ( fs . read ( this . file ) , '' ) . then ( c => {
this . content = c ;
} ) ;
} ,
renderWidget ( section _id , option _index , cfgvalue ) {
return E ( 'textarea' , {
'id' : 'widget.file_edit.content.' + this . id ,
'class' : 'cbi-input-textarea' ,
'style' : 'width:100% !important;resize:vertical !important' ,
'rows' : 10 ,
'wrap' : 'off' ,
'spellcheck' : 'false' ,
} , cfgvalue ) ;
} ,
} ) ,
load ( ) {
2021-11-04 18:57:08 +03:00
return Promise . all ( [
2026-03-04 16:22:22 +03:00
fs . exec ( tools . execPath , [ 'raw-status' ] ) ,
2023-01-09 18:11:41 +03:00
L . resolveDefault ( fs . list ( tools . parsersDir ) , null ) ,
uci . load ( tools . appName ) ,
2021-11-04 18:57:08 +03:00
] ) . catch ( e => {
ui . addNotification ( null , E ( 'p' , _ ( 'Unable to read the contents' )
+ ': %s [ %s ]' . format (
e . message , tools . parsersDir
) ) ) ;
} ) ;
} ,
2024-11-03 02:20:45 +03:00
render ( data ) {
2021-11-04 18:57:08 +03:00
if ( ! data ) {
return ;
} ;
2024-11-10 14:07:15 +03:00
this . appStatusCode = data [ 0 ] . code ;
let p _dir _arr = data [ 1 ] ;
let curent _module = uci . get ( tools . appName , 'config' , 'bllist_module' ) ;
let curent _preset = uci . get ( tools . appName , 'config' , 'bllist_preset' ) ;
2021-11-04 18:57:08 +03:00
if ( p _dir _arr ) {
p _dir _arr . forEach ( e => {
let fname = e . name ;
2026-02-16 18:21:55 +03:00
if ( fname . startsWith ( 'ruab_parser.' ) ) {
2023-01-09 18:11:41 +03:00
this . parsers [ fname ] = tools . parsersDir + '/' + fname ;
2021-11-04 18:57:08 +03:00
} ;
} ) ;
} ;
2023-01-09 18:11:41 +03:00
let availableParsers = Object . keys ( this . parsers ) . length > 0 ;
if ( ! availableParsers ) {
for ( let i of Object . keys ( tools . blacklistPresets ) ) {
if ( ! new RegExp ( '^($|' + tools . appName + ')' ) . test ( i ) && i !== curent _preset ) {
delete tools . blacklistPresets [ i ] ;
} ;
} ;
} ;
if ( curent _module ) {
this . parsers [ curent _module . match ( /([^/]*)$/ ) [ 0 ] ] = curent _module ;
} ;
2021-11-04 18:57:08 +03:00
let ip _filter _edit = new tools . fileEditDialog (
tools . ipFilterFile ,
_ ( 'IP filter' ) ,
2025-11-14 05:35:25 +03:00
_ ( 'Patterns can be strings or regular expressions. Each pattern in a separate line, the <code>#</code> symbol in the first position of a line will comment out the line.<br />Examples (dot is a special character):' ) +
'<br /><code>#comment<br /><code>128[.]199[.]0[.]0/16<br />34[.]217[.]90[.]52<br />162[.]13[.]190[.]</code>'
2021-11-04 18:57:08 +03:00
) ;
let fqdn _filter _edit = new tools . fileEditDialog (
tools . fqdnFilterFile ,
_ ( 'FQDN filter' ) ,
2025-11-14 05:35:25 +03:00
_ ( 'Patterns can be strings or regular expressions. Each pattern in a separate line, the <code>#</code> symbol in the first position of a line will comment out the line.<br />Examples:' ) +
'<br /><code>#comment<br /><code>poker<br />[ck]?a[sz]ino?<br />[vw]ulkan<br />slots?</code>'
2021-11-04 18:57:08 +03:00
) ;
2023-07-31 01:12:53 +03:00
let bypass _entries _edit = new tools . fileEditDialog (
tools . bypassEntriesFile ,
_ ( 'Exclusion list' ) ,
2025-11-14 05:35:25 +03:00
_ ( 'One entry (IP, CIDR or FQDN) per line. In the FQDN records, you can specify the DNS server for resolving this domain (separated by a space). You can also comment out the lines (<code>#</code> is the first character of a line).<br />Examples:' ) +
2023-07-31 01:12:53 +03:00
'<br /><code>#comment<br />domain.net<br />sub.domain.com 8.8.8.8<br />sub.domain.com 8.8.8.8#53<br />74.125.131.19<br />74.125.0.0/16</code>'
) ;
2021-11-04 18:57:08 +03:00
let torrc _edit = new tools . fileEditDialog (
tools . torrcFile ,
_ ( 'Tor configuration file' ) ,
null ,
function ( rc ) {
return tools . getInitStatus ( 'tor' ) . then ( res => {
if ( res ) {
return tools . handleServiceAction ( 'tor' , 'restart' ) ;
} ;
} ) ;
}
) ;
2024-09-23 00:52:58 +03:00
let gr _excluded _nets _edit = new tools . fileEditDialog (
tools . grExcludedNetsFile ,
_ ( 'IP subnet patterns (/24) that are excluded from optimization' ) ,
2025-11-14 05:35:25 +03:00
_ ( 'One IP subnet pattern (/24) per line. You can also comment out the lines (<code>#</code> is the first character of a line).<br />Examples:' ) +
2024-09-23 00:52:58 +03:00
'<br /><code>#comment<br />74.125.131.<br />74.125.0.</code>'
) ;
let gr _excluded _sld _edit = new tools . fileEditDialog (
tools . grExcludedSldFile ,
_ ( '2nd level domains that are excluded from optimization' ) ,
2025-11-14 05:35:25 +03:00
_ ( 'One FQDN entry per line. You can also comment out the lines (<code>#</code> is the first character of a line).<br />Examples:' ) +
2024-09-23 00:52:58 +03:00
'<br /><code>#comment<br />domain.net<br />anotherdomain.com</code>'
) ;
2024-11-03 02:20:45 +03:00
let m , s , o , ss ;
2021-11-04 18:57:08 +03:00
m = new form . Map ( tools . appName , _ ( 'Ruantiblock' ) + ' - ' + _ ( 'Settings' ) ) ;
s = m . section ( form . NamedSection , 'config' ) ;
s . anonymous = true ;
s . addremove = false ;
2023-02-06 17:27:15 +03:00
2025-09-15 18:25:20 +03:00
/* General settings tab */
2021-11-04 18:57:08 +03:00
2025-09-15 18:25:20 +03:00
s . tab ( 'general_tab' , _ ( 'General settings' ) ) ;
2021-11-04 18:57:08 +03:00
2022-05-05 18:28:32 +03:00
// ENABLE_LOGGING
2025-09-15 18:25:20 +03:00
o = s . taboption ( 'general_tab' , form . Flag , 'enable_logging' ,
2021-11-04 18:57:08 +03:00
_ ( 'Logging events' ) ) ;
o . rmempty = false ;
2022-05-10 01:22:25 +03:00
// update_at_startup
2025-09-15 18:25:20 +03:00
o = s . taboption ( 'general_tab' , form . Flag , 'update_at_startup' ,
2022-05-10 01:22:25 +03:00
_ ( 'Update at startup' ) ) ;
o . description = _ ( 'Update blacklist after system startup' ) ;
o . rmempty = false ;
2024-11-03 02:20:45 +03:00
// PROXY_LOCAL_CLIENTS
2025-09-15 18:25:20 +03:00
o = s . taboption ( 'general_tab' , form . Flag , 'proxy_local_clients' ,
2024-11-03 02:20:45 +03:00
_ ( 'Apply proxy rules to router application traffic' ) ) ;
o . rmempty = false ;
2023-02-06 17:27:15 +03:00
// NFTSET_CLEAR_SETS
2025-09-15 18:25:20 +03:00
o = s . taboption ( 'general_tab' , form . Flag , 'nftset_clear_sets' ,
2023-02-06 17:27:15 +03:00
_ ( 'Clean up nftsets before updating blacklist' ) ) ;
2021-11-04 18:57:08 +03:00
o . description = _ ( 'Reduces RAM consumption during update' ) ;
o . rmempty = false ;
2025-12-25 02:17:32 +03:00
// ENABLE_TMP_DOWNLOADS
o = s . taboption ( 'general_tab' , form . Flag , 'enable_tmp_downloads' ,
_ ( 'Safe blacklist update' ) ,
_ ( 'If update fails, the old blacklist configuration will be retained. Temporary files are used, when updating the blacklist (increases memory consumption).' ) ) ;
o . rmempty = false ;
o . default = 0 ;
2022-05-06 03:27:08 +03:00
// ALLOWED_HOSTS_MODE
2025-09-15 18:25:20 +03:00
o = s . taboption ( 'general_tab' , form . ListValue , 'allowed_hosts_mode' ,
2022-05-05 18:28:32 +03:00
_ ( 'Host filter' ) ) ;
o . value ( '0' , _ ( 'Disabled' ) ) ;
o . value ( '1' , _ ( 'Only listed hosts' ) ) ;
o . value ( '2' , _ ( 'All hosts except listed' ) ) ;
2025-09-15 18:25:20 +03:00
o . description = _ ( 'Restriction the local network hosts that are allowed to bypass blocking' ) ;
2022-05-05 18:28:32 +03:00
2022-05-28 20:17:52 +03:00
// ALLOWED_HOSTS_LIST
2025-09-15 18:25:20 +03:00
o = s . taboption ( 'general_tab' , form . DynamicList , 'allowed_hosts_list' ,
2023-08-29 17:43:52 +03:00
_ ( 'IP addresses for host filter' ) ) ;
2023-12-10 17:02:06 +03:00
o . datatype = 'ip4addr' ;
2023-08-29 17:43:52 +03:00
2025-09-15 18:25:20 +03:00
// BYPASS_MODE
o = s . taboption ( 'general_tab' , form . Flag , 'bypass_mode' ,
_ ( 'Enable exclusion list' ) , _ ( 'List of hosts that are excluded from block bypass (always available directly)' ) ) ;
o . rmempty = false ;
o . default = 0 ;
// BYPASS_ENTRIES edit dialog
o = s . taboption ( 'general_tab' , form . Button , '_bypass_entries_btn' ,
_ ( 'Exclusion list' ) ) ;
o . onclick = ( ) => bypass _entries _edit . show ( ) ;
o . inputtitle = _ ( 'Edit' ) ;
o . inputstyle = 'edit btn' ;
// BYPASS_ENTRIES_DNS
o = s . taboption ( 'general_tab' , form . Value , 'bypass_entries_dns' ,
_ ( 'DNS server that is used for the FQDN entries of exclusion list' ) , '<code>ipaddress[#port]</code>' ) ;
o . validate = this . validateIpPort ;
/* Main blacklist tab */
s . tab ( 'main_blacklist_tab' , _ ( 'Main blacklist' ) ) ;
o = s . taboption ( 'main_blacklist_tab' , form . SectionValue , 'config' , form . NamedSection ,
'config' ) ;
s . anonymous = true ;
s . addremove = false ;
ss = o . subsection ;
/* Main settings tab */
ss . tab ( 'b_settings_tab' , _ ( 'Main settings' ) ) ;
// PROXY_MODE
o = ss . taboption ( 'b_settings_tab' , form . ListValue , 'proxy_mode' ,
_ ( 'Proxy mode' ) ) ;
o . value ( '1' , 'Tor' ) ;
o . value ( '2' , 'VPN' ) ;
o . value ( '3' , _ ( 'Transparent proxy' ) ) ;
o . default = tools . defaultConfig . proxy _mode ;
// BLLIST_PRESET
let bllist _preset = ss . taboption ( 'b_settings_tab' , form . ListValue ,
'bllist_preset' , _ ( 'Blacklist update mode' ) ) ;
bllist _preset . description = _ ( 'Blacklist sources' ) + ':' ;
bllist _preset . value ( '' , _ ( 'user entries only' ) ) ;
Object . entries ( tools . blacklistPresets ) . forEach ( e => {
bllist _preset . value ( e [ 0 ] , ( ( e [ 1 ] [ 1 ] ) ? ` ${ e [ 1 ] [ 0 ] } - ${ e [ 1 ] [ 1 ] } ` : e [ 1 ] [ 0 ] ) ) ;
} ) ;
let bllist _sources = { } ;
Object . values ( tools . blacklistPresets ) . forEach ( v => { bllist _sources [ v [ 0 ] ] = v [ 2 ] } ) ;
Object . entries ( bllist _sources ) . forEach ( e => {
if ( e [ 1 ] ) {
bllist _preset . description += ` <br /> ${ e [ 0 ] } - <a href=" ${ e [ 1 ] } " target="_blank"> ${ e [ 1 ] } </a> ` ;
} ;
} ) ;
// BLLIST_MODULE
let bllist _module = ss . taboption ( 'b_settings_tab' , form . ListValue ,
'bllist_module' , _ ( 'Blacklist module' ) + '*' ) ;
bllist _module . value ( '' , _ ( 'disabled' ) ) ;
bllist _module . depends ( { bllist _preset : new RegExp ( '^($|' + tools . appName + ')' ) , '!reverse' : true } ) ;
Object . entries ( this . parsers ) . forEach (
e => bllist _module . value ( e [ 1 ] , e [ 0 ] ) ) ;
2025-11-14 05:35:25 +03:00
// ENABLE_BLLIST_PROXY
o = ss . taboption ( 'b_settings_tab' , form . Flag , 'enable_bllist_proxy' ,
_ ( 'Downloading a blacklist via proxy' ) , _ ( 'Turn on if blacklist source is blocked' ) ) ;
o . rmempty = false ;
o . default = 0 ;
2025-09-15 18:25:20 +03:00
// ENABLE_FPROXY
o = ss . taboption ( 'b_settings_tab' , form . Flag , 'enable_fproxy' ,
_ ( 'Enable full proxy mode' ) ) ;
o . description = _ ( 'All traffic of the specified hosts passes through the proxy, without a blacklist' ) ;
o . rmempty = false ;
o . default = 0 ;
// FPROXY_LIST
o = ss . taboption ( 'b_settings_tab' , form . DynamicList , 'fproxy_list' ,
_ ( 'IP addresses for full proxy mode' ) ) ;
o . datatype = 'ip4addr' ;
2021-11-04 18:57:08 +03:00
2023-02-06 17:27:15 +03:00
/* Tor tab */
2021-11-04 18:57:08 +03:00
2025-09-15 18:25:20 +03:00
ss . tab ( 'b_tor_tab' , _ ( 'Tor mode' ) ) ;
2021-11-04 18:57:08 +03:00
2023-02-06 17:27:15 +03:00
// TOR_TRANS_PORT
2025-09-15 18:25:20 +03:00
o = ss . taboption ( 'b_tor_tab' , form . Value , 'tor_trans_port' ,
2023-02-06 17:27:15 +03:00
_ ( 'Transparent proxy port' ) ) ;
o . rmempty = false ;
2024-11-06 15:30:03 +03:00
o . default = tools . defaultConfig . tor _trans _port ;
2023-12-10 17:02:06 +03:00
o . datatype = 'port' ;
2021-11-04 18:57:08 +03:00
2023-02-06 17:27:15 +03:00
// ONION_DNS_ADDR
2025-09-15 18:25:20 +03:00
o = ss . taboption ( 'b_tor_tab' , form . Value , 'onion_dns_addr' ,
2023-02-06 17:27:15 +03:00
_ ( "Optional DNS resolver for '.onion' zone" ) , '<code>ipaddress#port</code>' ) ;
o . rmempty = false ;
2024-11-06 15:30:03 +03:00
o . default = tools . defaultConfig . onion _dns _addr ;
2023-02-06 17:27:15 +03:00
o . validate = this . validateIpPort ;
2021-11-04 18:57:08 +03:00
2023-02-06 17:27:15 +03:00
// Torrc edit dialog
2025-09-15 18:25:20 +03:00
o = ss . taboption ( 'b_tor_tab' , form . Button , '_torrc_btn' ,
2023-02-06 17:27:15 +03:00
_ ( 'Tor configuration file' ) ) ;
o . onclick = ( ) => torrc _edit . show ( ) ;
o . inputtitle = _ ( 'Edit' ) ;
o . inputstyle = 'edit btn' ;
2021-11-04 18:57:08 +03:00
2023-02-06 17:27:15 +03:00
/* VPN tab */
2021-11-04 18:57:08 +03:00
2025-09-15 18:25:20 +03:00
ss . tab ( 'b_vpn_tab' , _ ( 'VPN mode' ) ) ;
2021-11-04 18:57:08 +03:00
2023-02-06 17:27:15 +03:00
// IF_VPN
2025-09-15 18:25:20 +03:00
o = ss . taboption ( 'b_vpn_tab' , widgets . DeviceSelect , 'if_vpn' ,
2023-02-06 17:27:15 +03:00
_ ( 'VPN interface' ) ) ;
o . multiple = false ;
o . noaliases = true ;
o . rmempty = false ;
2024-11-06 15:30:03 +03:00
o . default = tools . defaultConfig . if _vpn ;
2021-11-04 18:57:08 +03:00
2023-12-24 16:13:41 +03:00
// VPN_GW_IP
2025-09-15 18:25:20 +03:00
o = ss . taboption ( 'b_vpn_tab' , form . Value , 'vpn_gw_ip' ,
2023-12-24 16:13:41 +03:00
_ ( 'VPN gateway IP address' ) ,
_ ( 'If not specified, the VPN interface address is used (or peer address for PPP protocols)' ) ) ;
o . datatype = 'ip4addr(1)' ;
2021-11-04 18:57:08 +03:00
2024-11-03 02:20:45 +03:00
/* Tproxy tab */
2025-09-15 18:25:20 +03:00
ss . tab ( 'b_tproxy_tab' , _ ( 'Transparent proxy mode' ) ) ;
2021-11-04 18:57:08 +03:00
2024-11-03 02:20:45 +03:00
// T_PROXY_TYPE
2025-09-15 18:25:20 +03:00
o = ss . taboption ( 'b_tproxy_tab' , form . ListValue , 't_proxy_type' ,
2024-11-03 02:20:45 +03:00
_ ( 'Proxy type' ) ) ;
o . value ( '0' , _ ( 'redirect' ) ) ;
o . value ( '1' , _ ( 'tproxy' ) ) ;
o . description = _ ( 'Statement in nftables rules' ) ;
2021-11-04 18:57:08 +03:00
2023-02-06 17:27:15 +03:00
// T_PROXY_PORT_TCP
2025-09-15 18:25:20 +03:00
o = ss . taboption ( 'b_tproxy_tab' , form . Value , 't_proxy_port_tcp' ,
2023-02-06 17:27:15 +03:00
_ ( 'Transparent proxy TCP port' ) ) ;
o . rmempty = false ;
2024-11-06 15:30:03 +03:00
o . default = tools . defaultConfig . t _proxy _port _tcp ;
2023-12-10 17:02:06 +03:00
o . datatype = 'port' ;
2023-01-09 18:11:41 +03:00
2023-12-10 17:02:06 +03:00
// T_PROXY_ALLOW_UDP
2025-09-15 18:25:20 +03:00
o = ss . taboption ( 'b_tproxy_tab' , form . Flag , 't_proxy_allow_udp' ,
2023-12-10 17:02:06 +03:00
_ ( 'Send UDP traffic to transparent proxy' ) ) ;
2023-02-06 17:27:15 +03:00
o . rmempty = false ;
2024-11-06 15:30:03 +03:00
o . default = 0 ;
2023-01-09 18:11:41 +03:00
2023-02-06 17:27:15 +03:00
// T_PROXY_PORT_UDP
2025-09-15 18:25:20 +03:00
o = ss . taboption ( 'b_tproxy_tab' , form . Value , 't_proxy_port_udp' ,
2023-02-06 17:27:15 +03:00
_ ( 'Transparent proxy UDP port' ) ) ;
o . rmempty = false ;
2024-11-06 15:30:03 +03:00
o . default = tools . defaultConfig . t _proxy _port _udp ;
2023-12-10 17:02:06 +03:00
o . datatype = 'port' ;
2023-01-09 18:11:41 +03:00
if ( availableParsers ) {
bllist _preset . description += '<br /> ( * - ' + _ ( 'requires installed blacklist module' ) + ' )' ;
2021-11-04 18:57:08 +03:00
2023-01-09 18:11:41 +03:00
/* Parser settings tab */
2021-11-04 18:57:08 +03:00
2025-09-15 18:25:20 +03:00
ss . tab ( 'b_parser_settings_tab' , _ ( 'Module settings' ) ) ;
2021-11-04 18:57:08 +03:00
2023-01-14 15:53:19 +03:00
// BLLIST_MIN_ENTRIES
2025-09-15 18:25:20 +03:00
o = ss . taboption ( 'b_parser_settings_tab' , form . Value , 'bllist_min_entries' ,
2023-12-10 17:02:06 +03:00
_ ( 'Minimum allowed number of entries' ) ) ;
2023-01-14 15:53:19 +03:00
o . description = _ ( 'If less than the specified number of entries are received from the source, then the lists are not updated' ) ;
o . rmempty = false ;
o . datatype = 'uinteger' ;
2023-01-09 18:11:41 +03:00
// BLLIST_FQDN_FILTER
2025-09-15 18:25:20 +03:00
o = ss . taboption ( 'b_parser_settings_tab' , form . Flag , 'bllist_fqdn_filter' ,
2023-12-10 17:02:06 +03:00
_ ( 'Enable FQDN filter' ) ) ;
2023-01-14 15:53:19 +03:00
o . description = _ ( 'Pick domains from blacklist by FQDN filter patterns' ) ;
2023-01-09 18:11:41 +03:00
o . rmempty = false ;
2021-11-04 18:57:08 +03:00
2023-01-14 15:53:19 +03:00
// BLLIST_FQDN_FILTER_TYPE
2025-09-15 18:25:20 +03:00
o = ss . taboption ( 'b_parser_settings_tab' , form . ListValue , 'bllist_fqdn_filter_type' ,
2023-01-14 15:53:19 +03:00
_ ( 'FQDN filter type' ) ) ;
2023-01-15 02:27:23 +03:00
o . value ( '0' , _ ( 'All entries except matching patterns' ) ) ;
o . value ( '1' , _ ( 'Only entries matching patterns' ) ) ;
2023-01-14 15:53:19 +03:00
2023-01-09 18:11:41 +03:00
// BLLIST_FQDN_FILTER_FILE edit dialog
2025-09-15 18:25:20 +03:00
o = ss . taboption ( 'b_parser_settings_tab' , form . Button , '_fqdn_filter_btn' ,
2023-12-10 17:02:06 +03:00
_ ( 'FQDN filter' ) ) ;
2023-01-09 18:11:41 +03:00
o . onclick = ( ) => fqdn _filter _edit . show ( ) ;
o . inputtitle = _ ( 'Edit' ) ;
o . inputstyle = 'edit btn' ;
2021-11-04 18:57:08 +03:00
2023-01-09 18:11:41 +03:00
// BLLIST_SD_LIMIT
2025-09-15 18:25:20 +03:00
o = ss . taboption ( 'b_parser_settings_tab' , form . Value , 'bllist_sd_limit' ,
2023-12-10 17:02:06 +03:00
_ ( 'Subdomains limit' ) ) ;
2023-01-09 18:11:41 +03:00
o . description = _ ( 'The number of subdomains in the domain, upon reaching which the entire 2nd level domain is added to the list' ) ;
o . rmempty = false ;
o . datatype = 'uinteger' ;
2024-09-23 00:52:58 +03:00
// BLLIST_GR_EXCLUDED_SLD_FILE edit dialog
2025-09-15 18:25:20 +03:00
o = ss . taboption ( 'b_parser_settings_tab' , form . Button , '_gr_excluded_sld_btn' ,
2023-01-09 18:11:41 +03:00
_ ( '2nd level domains that are excluded from optimization' ) ) ;
2024-11-03 02:20:45 +03:00
o . onclick = ( ) => gr _excluded _sld _edit . show ( ) ;
o . inputtitle = _ ( 'Edit' ) ;
o . inputstyle = 'edit btn' ;
2023-01-09 18:11:41 +03:00
// BLLIST_ENABLE_IDN
2025-09-15 18:25:20 +03:00
o = ss . taboption ( 'b_parser_settings_tab' , form . Flag , 'bllist_enable_idn' ,
2023-12-10 17:02:06 +03:00
_ ( 'Convert cyrillic domains to punycode' ) ) ;
2023-01-09 18:11:41 +03:00
o . rmempty = false ;
2021-11-04 18:57:08 +03:00
2023-01-09 18:11:41 +03:00
// BLLIST_ALT_NSLOOKUP
2025-09-15 18:25:20 +03:00
o = ss . taboption ( 'b_parser_settings_tab' , form . Flag , 'bllist_alt_nslookup' ,
2023-01-09 18:11:41 +03:00
_ ( 'Use optional DNS resolver' ) ) ;
o . rmempty = false ;
2021-11-04 18:57:08 +03:00
2023-01-09 18:11:41 +03:00
// BLLIST_ALT_DNS_ADDR
2025-09-15 18:25:20 +03:00
o = ss . taboption ( 'b_parser_settings_tab' , form . Value , 'bllist_alt_dns_addr' ,
2023-12-10 17:02:06 +03:00
_ ( 'Optional DNS resolver' ) , '<code>ipaddress[#port]</code>' ) ;
2023-01-09 18:11:41 +03:00
o . rmempty = false ;
o . validate = this . validateIpPort ;
2021-11-04 18:57:08 +03:00
2023-01-09 18:11:41 +03:00
// BLLIST_IP_FILTER
2025-09-15 18:25:20 +03:00
o = ss . taboption ( 'b_parser_settings_tab' , form . Flag , 'bllist_ip_filter' ,
2023-12-10 17:02:06 +03:00
_ ( 'Enable IP filter' ) ) ;
2023-01-14 15:53:19 +03:00
o . description = _ ( 'Pick IP addresses from blacklist by IP filter patterns' ) ;
2023-01-09 18:11:41 +03:00
o . rmempty = false ;
2021-11-04 18:57:08 +03:00
2023-01-14 15:53:19 +03:00
// BLLIST_IP_FILTER_TYPE
2025-09-15 18:25:20 +03:00
o = ss . taboption ( 'b_parser_settings_tab' , form . ListValue , 'bllist_ip_filter_type' ,
2023-01-14 15:53:19 +03:00
_ ( 'IP filter type' ) ) ;
2023-01-15 02:27:23 +03:00
o . value ( '0' , _ ( 'All entries except matching patterns' ) ) ;
o . value ( '1' , _ ( 'Only entries matching patterns' ) ) ;
2023-01-14 15:53:19 +03:00
2023-01-09 18:11:41 +03:00
// BLLIST_IP_FILTER_FILE edit dialog
2025-09-15 18:25:20 +03:00
o = ss . taboption ( 'b_parser_settings_tab' , form . Button , '_ip_filter_btn' ,
2023-12-10 17:02:06 +03:00
_ ( 'IP filter' ) ) ;
2023-01-09 18:11:41 +03:00
o . onclick = ( ) => ip _filter _edit . show ( ) ;
o . inputtitle = _ ( 'Edit' ) ;
o . inputstyle = 'edit btn' ;
// BLLIST_IP_LIMIT
2025-09-15 18:25:20 +03:00
o = ss . taboption ( 'b_parser_settings_tab' , form . Value , 'bllist_ip_limit' , _ ( 'IP limit' ) ) ;
2023-01-09 18:11:41 +03:00
o . description = _ ( "The number of IP addresses in the subnet, upon reaching which the entire '/24' subnet is added to the list" ) ;
o . rmempty = false ;
o . datatype = 'uinteger' ;
2024-09-23 00:52:58 +03:00
// BLLIST_GR_EXCLUDED_NETS_FILE edit dialog
2025-09-15 18:25:20 +03:00
o = ss . taboption ( 'b_parser_settings_tab' , form . Button , '_gr_excluded_nets_btn' ,
2024-09-23 00:52:58 +03:00
_ ( 'IP subnet patterns (/24) that are excluded from optimization' ) ) ;
2024-11-03 02:20:45 +03:00
o . onclick = ( ) => gr _excluded _nets _edit . show ( ) ;
o . inputtitle = _ ( 'Edit' ) ;
o . inputstyle = 'edit btn' ;
2023-01-09 18:11:41 +03:00
// BLLIST_SUMMARIZE_IP
2025-09-15 18:25:20 +03:00
o = ss . taboption ( 'b_parser_settings_tab' , form . Flag , 'bllist_summarize_ip' ,
2023-12-10 17:02:06 +03:00
_ ( 'Summarize IP ranges' ) ) ;
2023-01-09 18:11:41 +03:00
o . rmempty = false ;
// BLLIST_SUMMARIZE_CIDR
2025-09-15 18:25:20 +03:00
o = ss . taboption ( 'b_parser_settings_tab' , form . Flag , 'bllist_summarize_cidr' ,
2023-01-09 18:11:41 +03:00
_ ( "Summarize '/24' networks" ) ) ;
o . rmempty = false ;
2024-11-03 02:20:45 +03:00
} ;
/* User entries tab */
s . tab ( 'user_entries_tab' , _ ( 'User entries' ) ) ;
o = s . taboption ( 'user_entries_tab' , form . SectionValue , 'user_instance' , form . GridSection ,
'user_instance' ) ;
ss = o . subsection ;
ss . addremove = false ;
ss . sortable = false ;
ss . nodescriptions = true ;
ss . modaltitle = ` ${ _ ( 'User entries' ) } - %s ` ;
ss . max _cols = 2 ;
/* User entries main settings tab */
ss . tab ( 'u_main_tab' , _ ( 'Main settings' ) ) ;
2025-09-15 18:25:20 +03:00
// description
o = ss . taboption ( 'u_main_tab' , form . Value , 'u_description' ,
_ ( "Description" ) ) ;
o . datatype = 'maxlength(50)' ;
o . modalonly = null ;
2024-11-03 02:20:45 +03:00
// U_ENABLED
o = ss . taboption ( 'u_main_tab' , form . Flag , 'u_enabled' ,
_ ( 'Enabled' ) ,
) ;
o . rmempty = false ;
2024-11-06 15:30:03 +03:00
o . default = 1 ;
2024-11-03 02:20:45 +03:00
o . editable = true ;
o . modalonly = false ;
// U_PROXY_MODE
o = ss . taboption ( 'u_main_tab' , form . ListValue , 'u_proxy_mode' ,
_ ( 'Proxy mode' ) ) ;
o . value ( '1' , 'Tor' ) ;
o . value ( '2' , 'VPN' ) ;
o . value ( '3' , _ ( 'Transparent proxy' ) ) ;
2024-11-06 15:30:03 +03:00
o . default = tools . defaultConfig . proxy _mode ;
2024-11-03 02:20:45 +03:00
o . modalonly = true ;
// U_ENABLE_FPROXY
o = ss . taboption ( 'u_main_tab' , form . Flag , 'u_enable_fproxy' ,
_ ( 'Enable full proxy mode' ) ) ;
o . description = _ ( 'All traffic of the specified hosts passes through the proxy, without a blacklist' ) ;
o . rmempty = false ;
2024-11-06 15:30:03 +03:00
o . default = 0 ;
2024-11-03 02:20:45 +03:00
o . modalonly = true ;
// U_FPROXY_LIST
o = ss . taboption ( 'u_main_tab' , form . DynamicList , 'u_fproxy_list' ,
_ ( 'IP addresses for full proxy mode' ) ) ;
o . datatype = 'ip4addr' ;
o . modalonly = true ;
/* User entries tor tab */
ss . tab ( 'u_tor_tab' , _ ( 'Tor mode' ) ) ;
// U_TOR_TRANS_PORT
o = ss . taboption ( 'u_tor_tab' , form . Value , 'u_tor_trans_port' ,
_ ( 'Transparent proxy port' ) ) ;
o . rmempty = false ;
2024-11-06 15:30:03 +03:00
o . default = tools . defaultConfig . tor _trans _port ;
2024-11-03 02:20:45 +03:00
o . datatype = 'port' ;
o . modalonly = true ;
// U_ONION_DNS_ADDR
o = ss . taboption ( 'u_tor_tab' , form . Value , 'u_onion_dns_addr' ,
_ ( "Optional DNS resolver for '.onion' zone" ) , '<code>ipaddress#port</code>' ) ;
o . rmempty = false ;
2024-11-06 15:30:03 +03:00
o . default = tools . defaultConfig . onion _dns _addr ;
2024-11-03 02:20:45 +03:00
o . validate = this . validateIpPort ;
o . modalonly = true ;
/* User entries VPN tab */
ss . tab ( 'u_vpn_tab' , _ ( 'VPN mode' ) ) ;
// U_IF_VPN
o = ss . taboption ( 'u_vpn_tab' , widgets . DeviceSelect , 'u_if_vpn' ,
_ ( 'VPN interface' ) ) ;
o . multiple = false ;
o . noaliases = true ;
o . rmempty = false ;
2024-11-06 15:30:03 +03:00
o . default = tools . defaultConfig . if _vpn ;
2024-11-03 02:20:45 +03:00
o . modalonly = true ;
// U_VPN_GW_IP
o = ss . taboption ( 'u_vpn_tab' , form . Value , 'u_vpn_gw_ip' ,
_ ( 'VPN gateway IP address' ) ,
_ ( 'If not specified, the VPN interface address is used (or peer address for PPP protocols)' ) ) ;
2025-09-15 18:25:20 +03:00
o . datatype = 'ip4addr(1)' ;
2024-11-03 02:20:45 +03:00
o . modalonly = true ;
/* User entries tproxy tab */
ss . tab ( 'u_tproxy_tab' , _ ( 'Transparent proxy mode' ) ) ;
// U_T_PROXY_TYPE
o = ss . taboption ( 'u_tproxy_tab' , form . ListValue , 'u_t_proxy_type' ,
_ ( 'Proxy type' ) ) ;
o . value ( '0' , _ ( 'redirect' ) ) ;
o . value ( '1' , _ ( 'tproxy' ) ) ;
o . description = _ ( 'Statement in nftables rules' ) ;
2025-09-15 18:25:20 +03:00
o . modalonly = true ;
2024-11-03 02:20:45 +03:00
// U_T_PROXY_PORT_TCP
o = ss . taboption ( 'u_tproxy_tab' , form . Value , 'u_t_proxy_port_tcp' ,
_ ( 'Transparent proxy TCP port' ) ) ;
o . rmempty = false ;
2024-11-06 15:30:03 +03:00
o . default = tools . defaultConfig . t _proxy _port _tcp ;
2024-11-03 02:20:45 +03:00
o . datatype = 'port' ;
o . modalonly = true ;
// U_T_PROXY_ALLOW_UDP
o = ss . taboption ( 'u_tproxy_tab' , form . Flag , 'u_t_proxy_allow_udp' ,
_ ( 'Send UDP traffic to transparent proxy' ) ) ;
2024-11-06 15:30:03 +03:00
o . rmempty = false ;
o . default = 0 ;
2024-11-03 02:20:45 +03:00
o . modalonly = true ;
// U_T_PROXY_PORT_UDP
o = ss . taboption ( 'u_tproxy_tab' , form . Value , 'u_t_proxy_port_udp' ,
_ ( 'Transparent proxy UDP port' ) ) ;
o . rmempty = false ;
2024-11-06 15:30:03 +03:00
o . default = tools . defaultConfig . t _proxy _port _udp ;
2024-11-03 02:20:45 +03:00
o . datatype = 'port' ;
o . modalonly = true ;
/* User entries items tab */
ss . tab ( 'u_entries_tab' , _ ( 'Entries' ) ) ;
ss . addModalOptions = ( s , section _id , ev ) => {
// user entries edit dialog
o = s . taboption ( 'u_entries_tab' , this . CBIBlockFileEdit , this ,
'user-entries' ,
tools . userListsDir + '/' + s . section ,
_ ( 'Edit entries' ) ,
2025-12-16 20:19:03 +03:00
_ ( 'One entry (IP, CIDR or FQDN) per line. In the FQDN records, you can specify the DNS server for resolving this domain (separated by a space). You can also comment out the lines (<code>#</code> is the first character of a line).<br />Examples:' ) +
2024-11-03 02:20:45 +03:00
'<br /><code>#comment<br />domain.net<br />sub.domain.com 8.8.8.8<br />sub.domain.com 8.8.8.8#53<br />74.125.131.19<br />74.125.0.0/16</code>'
) ;
o . modalonly = true ;
// U_ENTRIES_REMOTE
o = s . taboption ( 'u_entries_tab' , form . DynamicList , 'u_entries_remote' ,
_ ( 'URLs of remote user entries file' ) ) ;
2025-09-15 18:25:20 +03:00
o . validate = this . validateUrl ;
2024-11-03 02:20:45 +03:00
o . modalonly = true ;
// U_ENABLE_ENTRIES_REMOTE_PROXY
o = s . taboption ( 'u_entries_tab' , form . Flag , 'u_enable_entries_remote_proxy' ,
_ ( 'Downloading files via proxy' ) , _ ( 'Turn on if files are blocked' ) ) ;
o . rmempty = false ;
o . default = 0 ;
2023-01-09 18:11:41 +03:00
2024-11-03 02:20:45 +03:00
// U_ENTRIES_DNS
o = s . taboption ( 'u_entries_tab' , form . Value , 'u_entries_dns' ,
_ ( "DNS server that is used for the user's FQDN entries" ) , '<code>ipaddress[#port]</code>' ) ;
o . validate = this . validateIpPort ;
o . modalonly = true ;
2023-01-09 18:11:41 +03:00
} ;
2021-11-04 18:57:08 +03:00
let map _promise = m . render ( ) ;
map _promise . then ( node => node . classList . add ( 'fade-in' ) ) ;
2025-09-15 18:25:20 +03:00
2021-11-04 18:57:08 +03:00
return map _promise ;
} ,
2024-11-03 02:20:45 +03:00
handleSave ( ev , restart ) {
let tasks = [ ] ;
document . getElementById ( 'maincontent' )
. querySelectorAll ( '.cbi-map' ) . forEach ( ( map , i , a ) => {
let res = DOM . callClassMethod ( map , 'save' ) ;
if ( restart && i == a . length - 1 && this . appStatusCode != 1 && this . appStatusCode != 2 ) {
res . then ( ( ) => {
window . setTimeout ( ( ) => {
fs . exec _direct ( tools . execPath , [ 'restart' ] ) . then (
( ) => console . log ( tools . execPath + ' restarted...' )
) ;
2024-12-15 16:39:24 +03:00
} , 2000 ) ;
2024-11-03 02:20:45 +03:00
} ) ;
} ;
tasks . push ( res ) ;
} ) ;
return Promise . all ( tasks ) ;
} ,
handleSaveApply ( ev , mode ) {
return this . handleSave ( ev , true ) . then ( ( ) => {
2021-11-04 18:57:08 +03:00
ui . changes . apply ( mode == '0' ) ;
} ) ;
} ,
2020-06-19 20:43:08 +03:00
} ) ;